技术开发 频道

敏捷开发中要慎用继承

【IT168 技术文章】

    示例

    这是一个会议管理系统。用来管理各种各样的会议参与者信息。数据库里面有个表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的)。

0
相关文章