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章 慎用繼承

          示例

            這是一個(gè)會(huì)議管理系統(tǒng)。用來管理各種各樣的會(huì)議參與者信息。數(shù)據(jù)庫(kù)里面有個(gè)表Participants,里面的每條記錄表示一個(gè)參會(huì)者。因?yàn)榻?jīng)常會(huì)發(fā)生用戶誤刪掉某個(gè)參會(huì)者的信息。所以現(xiàn)在,用戶刪除時(shí),并不會(huì)真的刪除那參會(huì)者的信息,而只是將該記錄的刪除標(biāo)記設(shè)為true。24小時(shí)以后,系統(tǒng)會(huì)自動(dòng)將這條記錄刪除。但是在這24小時(shí)以內(nèi),如果用戶改變主意了,系統(tǒng)還可以將這條記錄還原,將刪除標(biāo)記設(shè)置為false。

            請(qǐng)認(rèn)真的讀下面的代碼:

          ??? 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這個(gè)方法只計(jì)算那些deleteFlags為false的記錄。也就是,被刪除的那些參會(huì)者不被計(jì)算在內(nèi)。

            上面的代碼看起來還不錯(cuò),但卻有一個(gè)很嚴(yán)重的問題。什么問題?先看看下面的代碼:

          ??? 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");

            最后一行代碼,會(huì)打印出"There are 1 participants"這樣信息,對(duì)不?錯(cuò)!它打印的是"There are 2 participants"!因?yàn)樽詈笠恍姓{(diào)用的是DBTable里面的這個(gè)方法getCount,而不是ParticipantsInDB的countParticipants。getCount一點(diǎn)都不知道刪除標(biāo)記這回事,它只是簡(jiǎn)單的計(jì)算記錄數(shù)量,并不知道要計(jì)算那些真正有效的參會(huì)者(就是刪除標(biāo)記為false的)。


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

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

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

          Feedback

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

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

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

          主站蜘蛛池模板: 丰镇市| 手游| 东丰县| 白玉县| 三都| 惠州市| 西青区| 天峻县| 济南市| 唐河县| 蓝山县| 久治县| 横峰县| 九江县| 翁牛特旗| 宁海县| 七台河市| 江门市| 五大连池市| 师宗县| 泉州市| 清河县| 监利县| 寿阳县| 潮州市| 桦甸市| 安龙县| 象山县| 桃源县| 加查县| 柳河县| 龙南县| 荣昌县| 原平市| 即墨市| 大余县| 鄢陵县| 平远县| 凯里市| 石门县| 昆明市|