当我们想要让一个类继承自另一个类时,我们一定要再三的检查:子类会不会继承了一些它不需要的功能(属性或者方法)?如果是的话,我们就得认真再想想:它们之间有没有真正的继承关系?如果没有的话,就用代理。如果有的话,将这些不用的功能从基类转移到另外一个合适的地方去。
示例
这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表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的记录。也就是,被删除的那些参会者不被计算在内。