第5章 慎用继承
示例
这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表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的)。
继承了一些不合适(或者没用的)的功能
下面的内容请到附件里查看。
分享到:
相关推荐
第5章:慎用继承 在面向对象编程中,继承是一种重要的机制,但过度依赖或误用可能导致复杂性增加。本章讨论了何时应该使用继承,以及如何合理地利用接口和组合来替代继承,以减少代码耦合,提高模块化和可扩展性。这...
#### 六、慎用继承 **1. 继承的滥用问题** - 过度使用继承可能导致类层次过于复杂。 - 继承层次结构的变动会影响所有子类。 **2. 使用继承的原则** - **遵循Liskov替换原则**:子类应该能够替换其父类。 - **...
#### 六、慎用继承 **继承的不当使用** - 过度依赖继承可能导致类之间的耦合度过高。 - 继承层次过深可能会增加系统的复杂度。 **正确使用继承的建议** 1. **优先考虑组合而非继承**:通过组合不同的类来达到...
#### 六、慎用继承 **1. 继承的局限性** - **过度继承可能导致代码耦合度过高**:过多的继承关系可能使代码变得难以理解和维护。 - **违反单一职责原则**:一个类如果承担太多的责任,可能会导致继承结构过于复杂。 ...