That way I want to stay

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            55 Posts :: 1 Stories :: 41 Comments :: 0 Trackbacks

          下載地址 


          http://www.aygfsteel.com/Files/Wingel/第5章慎用繼承.rar

          http://wingel.javaeye.com/topics/download/81eb4c8a-e19f-48a3-bcf9-1256053a1d79

          下面是摘錄的片段:


          第5章 慎用繼承

          示例

            這是一個會議管理系統(tǒng)。用來管理各種各樣的會議參與者信息。數據庫里面有個表Participants,里面的每條記錄表示一個參會者。因為經常會發(fā)生用戶誤刪掉某個參會者的信息。所以現(xiàn)在,用戶刪除時,并不會真的刪除那參會者的信息,而只是將該記錄的刪除標記設為true。24小時以后,系統(tǒng)會自動將這條記錄刪除。但是在這24小時以內,如果用戶改變主意了,系統(tǒng)還可以將這條記錄還原,將刪除標記設置為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的)。


          繼承了一些不合適(或者沒用的)的功能

          具體的內容在上面的下載鏈接里面的pdf文件里,看pdf比較舒服。

          posted on 2006-11-29 20:40 Wingel 閱讀(1218) 評論(3)  編輯  收藏 所屬分類: 敏捷開發(fā)

          Feedback

          # re: (原創(chuàng)翻譯) 敏捷開發(fā)的必要技巧5:慎用繼承 2006-11-30 12:52 Dustin Tang[匿名]
          觀點是對的, 例子就沒有舉到點子上.  回復  更多評論
            

          # re: (原創(chuàng)翻譯) 敏捷開發(fā)的必要技巧5:慎用繼承 2006-11-30 16:40 someone
          繼承沒有借口干凈,但是也不是什么時候都不如接口。
          這個例子沒有說明什么問題,如果父類里面getCount方法并不實現(xiàn),abstact或者拋異常的,強制在子類實現(xiàn),就是非常合適的用法。  回復  更多評論
            

          # re: (原創(chuàng)翻譯) 敏捷開發(fā)的必要技巧5:慎用繼承 2006-12-01 09:14 Wingel
          我這章的觀點并不是表達繼承不好,我的意思是說,要謹慎的使用繼承。如果將這個方法定義成abstract的話,那就不叫繼承自這個方法,而應該叫實現(xiàn)這個方法了。如果父類中不實現(xiàn)這個方法絕對是惡心的代碼,拋異常的話,那你就必須有足夠的testcase來保證邏輯的準備。  回復  更多評論
            

          主站蜘蛛池模板: 左云县| 太白县| 游戏| 应用必备| 清水县| 龙口市| 阳东县| 郁南县| 九龙坡区| 安阳县| 卓尼县| 兴安县| 邹城市| 巴彦县| 土默特左旗| 紫金县| 邳州市| 安达市| 承德县| 白银市| 鄄城县| 股票| 黑水县| 高阳县| 阳西县| 嘉义市| 克山县| 文昌市| 台东市| 鱼台县| 白朗县| 刚察县| 科技| 城步| 尉犁县| 新龙县| 通城县| 安义县| 正蓝旗| 特克斯县| 保山市|