这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表Participants,里面的每条记录表示一个参会者。因为经常会发生用户误删掉某个参会者的信息。所以现在,用户删除时,并不会真的删除那参会者的信息,而只是将该记录的删除标记设为true。
24小时以后,系统会自动将这条记录删除。但是在这24小时以内,如果用户改变主意了,系统还可以将这条记录还原,将删除标记设置为false。
请认真的读下面的代码:
public class DBTable {
protected Connection conn;
protected tableName;
public DBTable(String tableName) {
this。
tableName = tableName;
this。conn = 。。。;
public void clear() {
PreparedStatement st = conn。prepareStatement("DELETE FROM "+tableName);
try {
st。
executeUpdate();
}finally{
st。close();
public int getCount() {
PreparedStatement st = conn。prepareStatement("SELECT COUNT(*) FROM"+tableName);
try {
ResultSet rs = st。
executeQuery();
rs。next();
return rs。getInt
(1);
}finally{
st。close();
public class ParticipantsInDB extends DBTable {
public ParticipantsInDB() {
super("participants");
public void addParticipant(Participant part) {
public void deleteParticipant(String participantId) {
setDeleteFlag(participantId, true);
public void restoreParticipant(String participantId) {
setDeleteFlag(participantId, false);
private void setDeleteFlag(String participantId, boolean b) {
public void reallyDelete() {
PreparedStatement st = conn。prepareStatement(
"DELETE FROM "+
tableName+
" WHERE deleteFlag=true");
try {
st。
executeUpdate();
}finally{
st。close();
public int countParticipants() {
PreparedStatement st = conn。prepareStatement(
"SELECT COUNT(*) FROM "+
tableName+
" WHERE deleteFlag=false");
try {
ResultSet rs = st。
executeQuery();
rs。next();
return rs。getInt
(1);
}finally{
st。close();
注意到,countParticipants这个方法只计算那些deleteFlags为false的记录。
也就是,被删除的那些参会者不被计算在内。
上面的代码看起来还不错,但却有一个很严重的问题。什么问题?先看看下面的代码:
ParticipantsInDB partsInDB = 。。。;
Participant kent = new Participant(。
Participant paul = new Participant(。。。);
partsInDB。clear();
partsInDB。addParticipant(kent);
partsInDB。addParticipant(paul);
partsInDB。
deleteParticipant(kent。getId());
System。out。println("There are "+partsInDB。getCount()+ "participants");
最后一行代码,会打印出"There are 1 participants"这样信息,对不?错!它打印的是"There are 2 participants"!因为最后一行调用的是DBTable里面的这个方法getCount,而不是ParticipantsInDB的countParticipants。
getCount一点都不知道删除标记这回事,它只是简单的计算记录数量,并不知道要计算那些真正有效的参会者(就是删除标记为false的)。继承了一些不合适(或者没用的)的功能
ParticipantsInDB继承了来自DBTable的方法,比如clear和getCount。
对于ParticipantsInDB来讲,clear这个方法的确是有用的:清空所有的参会者。但getCount就造成了一点点小意外了:通过ParticipantsInDB调用getCount这个方法时,是取得participants这个表里面所有的记录,不管删除标记是true还是false的。
而实际上,没人想知道这个数据。即使有人想知道,这个方法也不应该叫做getCount,因为这名字很容易就会跟“计算所有的(有效)参会者数量”联系在一起。
因此,ParticipantsInDB是不是真的应该继承这个方法getCount呢?或者我们应该怎么做比较恰当呢?它们之间是否真的有继承关系?
当我们继承了一些我们不想要的东西,我们应该再三的想想:它们之间是不是真的有继承关系?ParticipantsInDB必须是一个DBTable吗?ParticipantsInDB希不希望别人知道它是一个DBTable?
实际上,ParticipantsInDB描述的是系统中所有的参会者的集合,该系统可以是个单数据库的,也可以是多数据库的,也就是说,这个类可以代表一个数据库里的一个Participants表,也可以代表两个数据库各自的两个Participants表的总和。