<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    That way I want to stay

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

    #

    here are four isolation levels:

  • READ UNCOMMITTED (在一個事務中,可能讀到別的事務還沒提交的數據)
  • READ COMMITTED(在一個事務中,同樣的語句可能查詢到不同的數據,因為在這兩個語句之間,別的事務更改提交了這兩個語句涉及的數據)
  • REPEATABLE READ(保證一個事務A里面讀到的數據不會變,即使期間別的事務B提交更改了數據,事務A中的語句仍然會讀到原來的數據)
  • SERIALIZABLE(在事務期間,會將涉及的數據鎖掉,防止別的事務修改)

    SQL server實現了四個級別
    Oracle只實現中間兩個級別。
     

  • 文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414835.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(84) | 評論 (0)編輯 收藏

    在一個Swing的項目中,每個控制用戶操作的action都是用new出來的,所以還要手動set一些被spring管理的對象。
    后來實在受不了這些冗余的代碼了,寫代碼的時候有時候又可能會把spring的對象跟非spring的對象順序弄亂了,讓代碼結構不清晰,在spring2的介紹中,聽說它連new出來的對象都可以管理,便去下了spring rc3來,布署到項目中。
      研究了半天,才發現其實是很容易的事,可憐我們看文檔看了半天。
    1。虛擬機加個參數:-javaagent:lib/aspectjweaver.jar(后面是spring帶的aspectjweaver.jar的路徑)
    2。在spring配置文件里面加:    <aop:spring-configured/>
    3。在要被管理的類中加上annotation:@Configurable(autowire = Autowire.BY_TYPE) autowire應該不用說了。  
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414836.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(111) | 評論 (0)編輯 收藏

      我們一般項目中,都是把字典存到數據庫中的。幾個月前在做一個政府的項目中,覺得其實一些字典是跟開發工程緊密結合在一起的,也就是說字典變了,工程肯定也要變,這樣子的字典如果也存到數據庫中的話,也是多增加一些麻煩而已,后來但將這些字典寫成枚舉。然后數據庫里面取的所謂的字典的key就是枚舉的name,如:"unsubmited",而前臺頁面顯示的,就是枚舉的一個屬性text,不過這里用到了webwork里面的ognl語法。

    /**
     * Author: Wingel
     * Date: 2006-7-29
     * Time: 15:17:52
     
    */

    public enum ApplicationState {
        unsubmited(
    "未提交"),submited("提交/待審批"),agreed("通過"),disagreed("未同意");
        
    private String text;

        ApplicationState(String text) 
    {
            
    this.text = text;
        }


        
    public static String getText(String name) {//給頁面用的方法
            try {
                
    return valueOf(name).text;
            }
     catch (Exception e) {
                
    return null;
            }

        }


        
    public String getText() {
            
    return text;
        }


        
    public static boolean isValidRegisterType(String name) {
            
    try {
                valueOf(name);
                
    return true;
            }
     catch (Exception e) {
                
    return false;
            }

        }


        
    public static ApplicationState[] allState() {
            
    return ApplicationState.values();
        }


        
    public String getName() {
            
    return this.name();
        }

    }



     

    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414837.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(229) | 評論 (0)編輯 收藏

      以前做完類似MonoRails的那個Java框架后,一直想把MonoRails里面那個Layout的功能也加到現在的開發框架里面,因為那框架確實是很有用啊。舉個例子吧,以前做頁面都是這樣子做的,做一個head.jsp,一個foot.jsp,然后在每個頁面里面這樣子做:
    <jsp:include file="head.jsp">
    <.....頁面代碼>
    <jsp:include file="footer.jsp">

    而現在的設想就是,在每個action的方法上加一個annotation,Layout,layout就是框架頁面的路徑,比如:main.jsp
    然后在main.jsp里面:
    <頁首的代碼>
    <pageFrame:body>
    <頁尾的代碼>
    這樣多省事啊。
    兩個月前動手要加這個功能的時候,突然有人告訴我,你干嘛不用一下sitemesh,于是就去了解了一下sitemesh。

    后來放棄的原來的打算,還是用sitemesh吧。






     
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414838.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(132) | 評論 (0)編輯 收藏

        sitemesh的一個問題,在web.xml中設置filter的時候,讓sitemesh可以過濾/*也就是所有的后綴名,但是在decorate.xml文件里面,并沒有給sitemesh增加gif,jpg等后綴的pattern,結果在打開頁面的時候,發現所有的圖像文件都引用失敗,用resin3的話,它會報錯說error content length,而用resin2或者tomcat的時候,它連報錯都沒有。弄了半天,都不明白是怎么回事,后來才想到有可能是sitemesh的問題,修改的filter的設置,讓它只過濾部分后綴名,結果就沒事了。
     
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414840.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(112) | 評論 (0)編輯 收藏

    前幾天同事講了Transaction isolation level,并且大家一起在SQLServer,Oracle跟MySQL數據庫上實驗了一下,發覺這些知識還是挺重要的。
    假如有兩個事務并發,順序如下
    Transaction A            Transaction B
    begin    begin
    query1 from table A   
    .......                  modify1 to table A(insert/update/delete)
       commit
    query2 from table A
    commit

    那么在事務A中,query1跟query2查詢出來的結果是否一樣呢?這就跟事務隔離級別有關了。
    SQL的標準定義里面,一共有四種級別:
    read uncommited讀取未提交的數據 就是其他事務求提交的數據,都可以讀取出來
    read commited讀取已提交的數據 query2會跟query1讀取的數據不一樣
    repeatable read可重復讀取,即query1跟query2讀取的數據是一樣的
    serializable 序列化,

     SQL 標準用三個必須在并行的事務之間避免的現象定義了四個級別的事務隔離。 這些不希望發生的現象是:
    臟讀(dirty reads)
        一個事務讀取了另一個未提交的并行事務寫的數據。
    不可重復讀(non-repeatable reads)
        一個事務重新讀取前面讀取過的數據, 發現該數據已經被另一個已提交的事務修改過。
    幻讀(phantom read)
        一個事務重新執行一個查詢,返回一套符合查詢條件的行, 發現這些行因為其他最近提交的事務而發生了改變。
     隔離級別         臟讀(Dirty Read)  不可重復讀(NonRepeatable Read)  幻讀(Phantom Read)
    讀未提交(Read uncommitted)   可能      可能                           可能
    讀已提交(Read committed)     不可能           可能                        可能
    可重復讀(Repeatable read)    不可能             不可能                    可能
    可串行化(Serializable )      不可能              不可能                  不可能

    SQLServer
    我們首先在SQLServer上做了實驗,SQLServer一共支持四種隔離級別,read uncommited跟read commited我們沒有實驗,我們直接先實驗
    repeatable read,如果事務A定義了如下級別,那么當事務B執行到modify1這條語句時,如果modify1是update的話,就被鎖起來,一直等
    到事務A提交完以后,鎖才會被釋放,而如果是insert的話,剛可以順利進行下去,然后在事務A中,query2查到的數據,是已經被事務B
    修改過的數據,如果將級別定義在serializable的話,則在modify1語句中,update,insert或者delete都會被鎖掉。
    也就是說,SQLServer對這些級別的支持,是通過鎖來做到的,雖然可以保證事務正常進行,但是并行的性能卻很差。
    Oracle
    oracle只支持兩個級別,read commited跟serializable,結果這里就不用詳細說明,實驗的結果是,oracle的serializable是通過版本
    控制來完成的,而不是通過鎖機制,這就保證了并行的性能。Oracle的默認級別是read commited
    MySQL
    MySQLServer也支持四個級別,而且MySQL也是通過版本控制而非鎖機制來完成的。
     


    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414839.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(190) | 評論 (0)編輯 收藏

    想搭建一個框架是使用AJAX的,首先考慮到的就是Google web toolkit,看了一下它的文檔,就是將所有的dom元素封裝成Java對象了,寫起代碼來,因為有IDE的幫助,而且憑著靜態語法的特點,出錯的機率就小了。但是有這樣一個問題,比如說想給頁面上隨便增加一點東西的話,卻不能隨便編輯html文件,因為GWT生成的代碼并不是那么好讀,也就是說,每次要修改一下頁面,就要重新再編譯一下Java代碼。這點可不好。后來就改用YUI了,YUI的example 倒是非常的豐富,但用了總感覺不舒服,后面想想,才明白是因為它的api設計得不好調用,代碼不能寫得很簡潔。沒得說,又去試了一下dojo了,感覺是簡潔得多了,api用了感覺挺舒服的。寫頁面的時候,想用一下prototype的$,之前還以為dojo是基于prototype寫成的,結果試了半天,才發現并不是這樣,正巧又在網上看了一篇介紹jQuery的,試了一下,就迷上它了,然后就把dojo從項目中移走了。
      仔細回想了這四個框架,想想自己為什么會選中jQuery。才發現,因為jQuery的源代碼是最簡潔的,結構上也是最容易全部掌握了,寫JavaScript代碼的時候,總是希望所有的代碼都是在自己的手里面控制的,這種想法,跟一年前的想法一模一樣,當時AJAX剛火的時候,也想去試一些開源的框架,但用了一段時間以后,就放棄了,全部使用了自己設計的框架,因為框架掌握在自己手里面,舒坦。
      JavaScript庫豐富固然好,但是越豐富,自己就越不了解全部層次,內心就越不安。不懂這是不是大多數人的通病。可是仔細想想,為什么Java的開源庫用得這么自在,為什么JavaScript的就自在不起來呢。 
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414843.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(111) | 評論 (0)編輯 收藏

    用jquery碰到的問題
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414850.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(113) | 評論 (0)編輯 收藏

    上回碰到一個項目要求是要求寫一個桌面程序,而這個程序的要求是越少占用資源越好,越小越好。
    雖然最近一直在寫swing的程序,但Java肯定是不能用了,因為還怎么打包都要8M以上;.net的winform也是不能用了,;就只剩三個選擇了,Delphi,VB跟MFC,MFC實在是不想用,就先試了下用VB寫,正在寫得很不爽的時候,在某個地方查到VB還要拷一些dll文件才能正常運行,于是就只剩下Delphi,后來終于在很痛苦的情況下,把程序完成了,唉,好的IDE用習慣了,對它的依賴也變得很多。(沒錯,我這里就是在暗示Delphi這個IDE真TMD太差了)
      后來才聽說了,C++有個庫,叫QT,寫桌面程序非常的不錯,還很像swing。嗚!真TMD的知道得太遲了,還被折磨了很久,查了暴多的資料。 
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414851.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(97) | 評論 (0)編輯 收藏

      其實這種事情都會有兩個觀點。
    一個觀點是:建議使用自己熟悉的技術,采用簡單的架構去實現項目,等到你把項目做出來了,能用起來了,客戶認可了。以后的升級,那是你就可以比較輕松的采用其 它的架構來重構,這樣你的風險,壓力就相對減少很多了。
    而這回,我想頂一下第二個觀點:  
      其實如果你對代碼要求比較嚴格的話,你就會經常發現,你的代碼有很多東西可以抽取出來,或者做在公共的模塊,或者作為框架的底層,我們就簡單的拿jdbc來說吧,
        首先,是connection的管理,這點一般用jdbc熟一些的話,都會有管理connection的公共模塊,雖然偶爾會碰到性能的問題,但是這點我們暫且壓下不表。
        我們查詢的時候,每次都要用
        rs.get...("name"),
        rs.get...("id"),
        rs.get...("age"),
        rs.get...("gender"),
        rs.get...("hobby"),
        然后修改數據庫的時候,還要拼寫update語句跟insert語句,經常還要費很多時間來調試這些多余代碼的問題,這時候你就想,不行,我一定要寫一個公共模塊,省得讓我每次都要定這么多代碼,于是你的第一個公共模塊產生了,然后測試啊測試,改進啊改進,叮叮響,過了幾天時間的考驗,這個公共模塊終于可以放心使用了,項目進度開始快一些了,總算不用再拼SQL了。
       
        后來在做統計模塊的時候,突然又發現,之前在用到的一些SQL函數,好像在客戶要求的數據庫上不怎么行啊,于是又去查了一下資料,又過了幾天(可能這次不用幾天),然后終于放心,所有的函數都正常了。
       
        接著又不可避免的碰到了分頁的問題,你對自己說,不用怕,我上回就寫了一個分頁的,沒有問題!可是Ya的你突然發現,上回的那個分頁是用游標實現的,這回客戶是要求用SQLServer,唉,SQLServer的游標,不提也罷,想來想去,只好自己拼SQL語句來寫分頁了,又是count又是top,測了又測之后,又過了幾天,啊哈,終于分頁的公共模塊也做好的,可以放心使用了,好,項目的進度又可以加快了。

        做著做著的時候,發現,咦,好像這表得增加一個字段才行,增加了,然后所有查詢的SQL語句加一下,所有insert跟update的代碼修改一下,頁面修改一下,嗯,現在應該正常了,看起來倒是沒什么問題,咦,報表好像不怎么對啊,靠,這邊還有調用這個表的代碼,媽的,改吧改吧。磨蹭了好幾個小時(當然,熟練的話,并不用幾個小時),總算看起來都正常了。

        這一回,這個功能中有一次用戶請求,訪問了好幾次數據庫,不行,這里應該用個cache,否則性能上會有問題啊,算了,用算法解決一下,盡量少訪問數據庫好了,我對cache還不熟呢。(寫啊寫啊,Batch Size,這樣多,那樣多,Fetch Size。。。,終于,看起來正常一些了)。過了一段時間,靠,這邊又要訪問好幾次數據庫,Ya的受不鳥了,性能愛咋的咋的,反正一個地方慢又不要緊。Oh shit!!!這邊也是好幾次,這邊又是好幾次,那邊又是好幾次。不行了,我老老實實寫個cache支持吧,于是又叮叮當當了好幾天,終于,有個粗糙的cache出來了,終于速度可以看一些了。后來改進又改進,測試又測試,累死了,老子好不爽啊。

        好像天下有點太平了,啊,你說我這個地方忘記更新你增加的那個子表啊,算了,沒關系,我明天看一下代碼,這個容易解決點。嗯,我改了那邊的代碼了,會更新子表信息了。什么?你說取主表的記錄跟相應的子表記錄列表麻煩啊,沒關系,我更新一下處理resultset的公共模塊,明天再說。
        Oh shit......對這樣子復雜的查詢好像現在的公共模塊支持不了啊,算了,這樣子的查詢不要用這個公共模塊,我們手動寫一些代碼好啊,別跟我講這樣代碼結構很難看,你以為我不知道啊,TMD。

        TMD的,怎么這邊的SQL老是運行不了啊,不會是分頁底層模塊的問題吧,靠,怎么你的SQL語句有這么多order,group by,靠,還有top啊,這當然過不了了,不要吵了,現在時間改,不理它,直接用個假分頁就行了。你又說代碼結構難看,小心我抽你哦。

        公司新來一個程序員,看了幾天代碼,不停的抱怨說,這代碼寫得真差啊。。。。。。 


    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414852.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(95) | 評論 (0)編輯 收藏

    目前jQuery網站上已經有了From的驗證框架,FromValidation,但是一直覺得它的框架并不好用,因為重復寫的東西太多了。
    于是就再次寫了自己的JavaScript驗證框架,完全廢棄掉以前的。
    在新的框架下,是以這樣子的用法設計的:
    首先,要包括自己的js文件(這點不必說),而且在包括自己寫,要先包括jQuery的,如下

    <link rel="stylesheet" type="text/css" href="<ww:url value="/layout/css/style.css"/>">
    <link rel="stylesheet" type="text/css" href="<ww:url value="/layout/css/thickbox.css"/>" media="screen">
    <script type="text/javascript" src="<ww:url value="/layout/js/jquery-latest.js"/>"></script>
    <script type="text/javascript" src="<ww:url value="/layout/js/thickbox.js"/>"></script>
    <script type="text/javascript" src="<ww:url value="/layout/js/wingel.js"/>"></script>
    <decorator:head/>


    然后在要驗證的Form里面加個屬性validatable=true,如下:

    <form id="registerForm" action="user-register.action" validatable="true">

    注意,這邊不要加onsubmit方法

    接下來,就好了,比如說有個輸入框:
    <ww:textfield name="name" id="name"/>
    我想驗證,讓它必填,如下就可以了:
    <label for="name" validate="required">請填寫名稱</label>  其中 for屬性里面填的要是驗證的輸入框id,validate填的是驗證方法,;label里面的文本就是驗證不過的時候要顯示的信息。
    如果我想驗證一個輸入框的輸入值長度怎么辦,這樣子就行了

    <label for="password" validate="lengthRange:6;20">

    后面的參數用;號隔開,驗證的方法名跟參數用: 隔開。
    wingel.js里面已經包括了一些常用的驗證方法,現在問題來了,如果要自定義驗證方法怎么辦,如下辦:
    比如你想加個驗證方法是hello
    則label里面的validate屬性寫成hello,
    然后加一個JavaScript方法:

    <script type="text/javascript">
        wingel.validator.rules.hello
    = function(value, element, parameters,utility) {
                 ...    }

    </script>


    里面三個參數,shit , couldn't input Chinese. now English will be used.

    The first parameter is the value of the input element you want to validate,the second one is the validated element, the third one, is the parameters you add in validate label, the last one, is a utility class, you can invoke its method to make your code easier.






     
    文章來源:http://blog.csdn.net/Wingel/archive/2006/11/26/1414856.aspx
    posted @ 2006-11-29 11:18 Wingel 閱讀(263) | 評論 (0)編輯 收藏

    完整書籍
    http://www.tkk7.com/Files/Wingel/第4章 保持代碼簡潔.rar

    第4章 保持代碼簡潔

    第4章? 保持代碼簡潔

    ????
    示例

    ??? 這是一個會議管理系統。它用來管理所有參會者的信息。剛開始的時候,我們只需要記錄每個參會者的ID(這是會議組織者分配的),姓名,電話和地址就行。于是,我們寫了如下的代碼:
    ???
    ??? class Participant {???????????????????????????????????????????????????????????????????????????
    ?????? String id;?????????????????????????????????????????????????????????????????????????????????
    ?????? String name;???????????????????????????????????????????????????????????????????????????????
    ?????? String telNo;??????????????????????????????????????????????????????????????????????????????
    ?????? String address;????????????????????????????????????????????????????????????????????????????
    ??? }???
    ???
    ??? class ConferenceSystem {??????????????????????????????????????????????????????????????????????
    ?????? Participant participants[];????????????????????????????????????????????????????????????????
    ??? }?????????????????????????????????????????????????????????????????????????????????????????????

    ??? 接著,新的需求來了:現在每個參會者都可以讓組織者幫忙預訂酒店,所以我們要記錄下他想預訂的酒店名,入住日期,離開日期,房間類型(單人房或者雙人房)。于是我們又擴充成如下的代碼:???

    ??? class Participant {???????????????????????????????????????????????????????????????????????????
    ?????? String id;?????????????????????????????????????????????????????????????????????????????????
    ?????? String name;???????????????????????????????????????????????????????????????????????????????
    ?????? String telNo;??????????????????????????????????????????????????????????????????????????????
    ?????? String address;????????????????????????????????????????????????????????????????????????????
    ?????? boolean bookHotelForHim;???????????????????????????????????????????????????????????????????
    ?????? String hotelName;??????????????????????????????????????????????????????????????????????????
    ?????? Date checkInDate;??????????????????????????????????????????????????????????????????????????
    ?????? Date checkOutDate;?????????????????????????????????????????????????????????????????????????
    ?????? boolean isSingleRoom;??????????????????????????????????????????????????????????????????????
    ?????? void setHotelBooking(String hotelName, Date checkInDate, ...) {????????????????????????????
    ?????????? ...????????????????????????????????????????????????????????????????????????????????????
    ?????? }??????????????????????????????????????????????????????????????????????????????????????????
    ??? }?????????????????????????????????????????????????????????????????????????????????????????????

    ??? 接著,又有一個新的需求來了:參會者可以參加不同的研討會,所以我們要記錄下參會者參加的研討會。對于他要參加的每一場研討會,我們還要記錄下他的登記時間,同時他還需要什么翻譯設備。于是代碼又擴充成:

    具體的內容在上面的下載鏈接里面的pdf文件里。

    完整書籍
    http://www.tkk7.com/Files/Wingel/%E7%AC%AC4%E7%AB%A0%E4%BF%9D%E6%8C%81%E4%BB%A3%E7%A0%81%E7%AE%80%E6%B4%81.rar
    posted @ 2006-11-28 20:51 Wingel 閱讀(1322) | 評論 (7)編輯 收藏

    ? http://www.tkk7.com/Files/Wingel/第3章%20除去代碼異味.rar
    ??????????????? 第3章 除去代碼異味 


    ??? 異味這個詞,可能有點抽象,我們先看一下下面的例子

    ??? 這是一個CAD系統. 現在,它已經可以畫三種形狀了:線條,長方形,跟圓.
    先認真的看一下下面的代碼:

    ??? class Shape {??????????????????????????????????????????????????????????????????????????????????
    ?????? final static int TYPELINE = 0;??????????????????????????????????????????????????????????????
    ?????? final static int TYPERECTANGLE = 1;?????????????????????????????????????????????????????????
    ?????? final static int TYPECIRCLE = 2;????????????????????????????????????????????????????????????
    ?????? int shapeType;??????????????????????????????????????????????????????????????????????????????
    ?????? //線條的開始點
    ?????? //長方形左下角的點
    ?????? //圓心
    ?????? Point p1;???????????????????????????????????????????????????????????????????????????????????
    ?????? //線條的結束點
    ?????? //長方形的右上角的點
    ?????? //如果是圓的話,這個屬性不用
    ?????? Point p2;???????????????????????????????????????????????????????????????????????????????????
    ?????? int radius;?????????????????????????????????????????????????????????????????????????????????
    ??? }??????????????????????????????????????????????????????????????????????????????????????????????
    ??? class CADApp {?????????????????????????????????????????????????????????????????????????????????
    ?????? void drawShapes(Graphics graphics, Shape shapes[]) {????????????????????????????????????????
    ?????????? for (int i = 0; i < shapes.length; i++) {???????????????????????????????????????????????
    ?????????????? switch (shapes[i].getType()) {??????????????????????????????????????????????????????
    ????????????????? case Shape.TYPELINE:?????????????????????????????????????????????????????????????
    ????????????????????? graphics.drawLine(shapes[i].getP1(), shapes[i].getP2());?????????????????????
    ????????????????????? break;???????????????????????????????????????????????????????????????????????
    ????????????????? case Shape.TYPERECTANGLE:????????????????????????????????????????????????????????
    ????????????????????? //畫四條邊
    ????????????????????? graphics.drawLine(...);??????????????????????????????????????????????????????
    ????????????????????? graphics.drawLine(...);??????????????????????????????????????????????????????
    ????????????????????? graphics.drawLine(...);??????????????????????????????????????????????????????
    ????????????????????? graphics.drawLine(...);??????????????????????????????????????????????????????
    ????????????????????? break;???????????????????????????????????????????????????????????????????????
    ????????????????? case Shape.TYPECIRCLE:???????????????????????????????????????????????????????????
    ????????????????????? graphics.drawCircle(shapes[i].getP1(), shapes[i].getRadius());???????????????
    ????????????????????? break;???????????????????????????????????????????????????????????????????????
    ?????????????? }???????????????????????????????????????????????????????????????????????????????????
    ?????????? }???????????????????????????????????????????????????????????????????????????????????????
    ?????? }???????????????????????????????????????????????????????????????????????????????????????????
    ??? }??????????????????????????????????????????????????????????????????????????????????????????????


    ??? 代碼都是一直在改變的,而這也是上面的代碼會碰到的一個問題.

    ??? 現在我們有一個問題: 如果我們需要支持更多的形狀(比如三角形), 那么肯定要改動Shape這個類, CADApp里面的drawShapes這個方法也要改.
    好,改為如下的樣子:
    ??
    ......


    ??? 如果我們想要支持更多的圖形(比如:三角形),上面沒有一個類需要修改。我們只需要創建一個新的類Triangle就行了。

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

    http://www.tkk7.com/Files/Wingel/第3章%20除去代碼異味.rar
    posted @ 2006-11-27 21:23 Wingel 閱讀(1998) | 評論 (3)編輯 收藏

    ? http://www.tkk7.com/Files/Wingel/敏捷開發的必要技巧第1,2章.rar???????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????? 第1章 移除重復代碼
    ???????????????????????????????????????????????????????????????????????????????
    重復代碼是怎么產生的?

    請觀察下面的代碼,我們已經有一個根據出租記錄的id取出租用客戶的姓名的方法:getCustomerName。

    ??? public class BookRental { //該類描述出租記錄
    ??????? String id;
    ??????? String customerName;

    ??????? ...

    ??? }
    ??? public class BookRentals {
    ?????? private Vector rentals;
    ?????? public String getCustomerName(String rentalId) { 根據出租id取出客戶姓名
    ?????????? for (int i = 0; i < rentals.size(); i++) {
    ????????????? BookRental rental = (BookRental) rentals.elementAt(i);
    ????????????? if (rental.getId().equals(rentalId)) {
    ????????????????? return rental.getCustomerName();
    ?????????????? }
    ?????????? }
    ?????????? throw new RentalNotFoundException();
    ??????? }
    ??? }
    ??? public class RentalNotFoundException extends Exception {

    ??????? ...

    ??? }

    假定現在你要增加一個新的方法,該方法是根據出租記錄的id刪除該記錄,然后把它命名為deleteRental(String rentalId)。現在你已經考慮到,就像getCustomerName這個方法一樣,你要一個一個遍歷出租記錄。所以你就將getCustomerName這個方法里面的一些代碼拷出來,然后稍微修改一下:

    ??
    .....


    為什么我們要移除重復代碼?

    我來向各位程序員同學稍微說一下,在BookRentals這個類中,rentals這個屬性的類型是Ventor,如果我們需要將它改為數組,那我們就必須將所有的"rentals.size()"改為"rentals.length". 在重構以后的版本中,我們只需要在getRentalIdxById這個方法中修改一次,而在原來的版本,我們就得在getCustomerName跟deleteRental兩個方法中都改一次。類似的,我們還要將所有的"rentals.elementAt(i)" 改為 "rentals[i]". 又是改一次跟改兩次的比較!

    大多數情況中,如果類似這樣的代碼在10個地方重復,當我們修改代碼的時候,就要修改10個地方,我們并不能保證能把這10個地方都記住了,而一旦漏掉了幾個地方,等待我們的,是一處一處的錯誤去修復。而最致命的是,當我們修改的是業務邏輯時,這時候,不管我們漏掉了幾個地方,IDE都不會報錯,那么,等待我們的,將一堆去檢查,而造成的一些bug中,很可能是短時間內還發現不了了.慘-_-!!

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

    http://www.tkk7.com/Files/Wingel/敏捷開發的必要技巧第1,2章.rar
    posted @ 2006-11-27 21:22 Wingel 閱讀(1956) | 評論 (0)編輯 收藏

    僅列出標題
    共2頁: 上一頁 1 2 
    主站蜘蛛池模板: 亚洲一区二区三区首页| 久久永久免费人妻精品下载| 亚洲一区二区三区深夜天堂| 亚洲国产成人乱码精品女人久久久不卡| 久久免费精彩视频| 国产高清对白在线观看免费91| 亚洲久悠悠色悠在线播放| 久久久久久久久亚洲| 中文字幕专区在线亚洲| 国产高清在线精品免费软件| 黄+色+性+人免费| 久久久久久久99精品免费观看 | 无码午夜成人1000部免费视频 | 亚洲区小说区图片区| 蜜臀91精品国产免费观看| 91麻豆最新在线人成免费观看| 免费一级毛片无毒不卡| 国产亚洲精品免费视频播放| 特级做a爰片毛片免费看| 国产亚洲一卡2卡3卡4卡新区| 亚洲欧美日韩一区二区三区在线| 亚洲人成黄网在线观看| 亚洲综合久久成人69| 99人中文字幕亚洲区| 久久亚洲AV无码精品色午夜麻豆| 亚洲VA中文字幕无码一二三区 | 亚洲第一综合天堂另类专| 久久夜色精品国产噜噜亚洲a| 亚洲一区电影在线观看| 亚洲资源最新版在线观看| 亚洲videosbestsex日本| 亚洲永久中文字幕在线| 亚洲欧洲国产综合| 亚洲国产人成在线观看| 亚洲av无码片在线观看| 2020久久精品亚洲热综合一本| 国产精品亚洲综合久久| 亚洲成av人在线观看网站| 国产午夜亚洲精品不卡电影| 新最免费影视大全在线播放| 国产激情久久久久影院老熟女免费 |