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

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

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

    John Jiang

    a cup of Java, cheers!
    https://github.com/johnshajiang/blog

       :: 首頁(yè) ::  :: 聯(lián)系 :: 聚合  :: 管理 ::
      131 隨筆 :: 1 文章 :: 530 評(píng)論 :: 0 Trackbacks
    編寫(xiě)好的面向?qū)ο蟠a

        本文是java.net上的一篇博客,作者Curtis Cooley對(duì)編寫(xiě)好的面向?qū)ο蟠a有些建議,希望對(duì)大家都有所幫助。(2008.10.08最后更新)

    獲取經(jīng)驗(yàn)沒(méi)有捷徑。編寫(xiě)好的面向?qū)ο蟠a需要經(jīng)驗(yàn),但這兒有三種做法能幫你在一開(kāi)始就很順利,即便你是老頑固:
        1. 使用測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)編寫(xiě)你所有的代碼
        2. 遵循簡(jiǎn)單法則
        3. 告之而非問(wèn)之

    使用TDD編寫(xiě)所有代碼
        按測(cè)試先行編寫(xiě)的代碼與按測(cè)試后行編寫(xiě)的代碼是極為不同的代碼。按測(cè)試先行編寫(xiě)的代碼是松耦合與高聚合的。當(dāng)某個(gè)屬性或私有方法需要暴露給測(cè)試程序時(shí),按測(cè)試后行編寫(xiě)的代碼常會(huì)打破封裝,因?yàn)樵擃惒⒉皇菫榱藴y(cè)試而設(shè)計(jì)的。如果你首先編寫(xiě)測(cè)試代碼,你的依賴將會(huì)更好,你的代碼將是松耦合與高聚合的。后面會(huì)有更多關(guān)于測(cè)試能幫助你設(shè)計(jì)更佳代碼的內(nèi)容。

    遵循簡(jiǎn)單法則
        代碼是簡(jiǎn)單的,只要當(dāng)它:
        1. 執(zhí)行了所有的測(cè)試
        2. 不包含重復(fù)
        3. 表達(dá)了所有的意圖
        4. 使用最少的類和方法
    注意到我用的是個(gè)被排序了的列表是很重要的。順序是重要的。只有一個(gè)main()方法的的GodClass[1]不會(huì)是簡(jiǎn)單的。這個(gè)類可能執(zhí)行了所有的測(cè)試,但在任何比"Hello, world!"更復(fù)雜的程序中,它肯定包含了重復(fù),并且也沒(méi)有表達(dá)出全部的意圖。
    我努力使用簡(jiǎn)單法則去關(guān)注If問(wèn)題。我不知道如何使用簡(jiǎn)單法則去阻止某人編寫(xiě)重量級(jí)的If代碼。有人可能會(huì)提出不同意見(jiàn),我也嘗試過(guò),但這樣的重量級(jí)If代碼確實(shí)無(wú)法表達(dá)意圖。但當(dāng)你閱讀如下代碼時(shí)

    if (mobile.getType() == MobileTypes.STANDARD) {
      alert();
    }
    確實(shí)難以看出其中的意圖。這些代碼無(wú)論處于哪個(gè)方法的上下文環(huán)境中,我們都能知道,如果mobile是STANDARD類型的話,那么就報(bào)警。而你所需要的更多意圖呢?
    我還有一點(diǎn)兒靈感顯現(xiàn)。如果有那樣的代碼,那么在其它地方肯定還會(huì)有更多那樣的代碼。這些代碼可能就像:
    if (mobile.getType() == MobileTypes.GAS) {
      registerGasReading();
    }

    if (mobile.getType() == MobileTypes.TEXT) {
      sendTextMessage();
    }

    if (mobile.getType() == MobileTypes.LOCATION) {
      notifyLocation();
    }
    你看出來(lái)了嗎?我是看出來(lái)了。它違反了規(guī)則2,有很多地方都違反了規(guī)則2,并且是一種最壞的情形。這段代碼有多處重復(fù)。重復(fù)將極難發(fā)現(xiàn)。所以,請(qǐng)幫助防止這種情形的發(fā)生,我已包含其中了。

    告之而非問(wèn)之
    簡(jiǎn)言之,告之而非問(wèn)之意指不要先問(wèn)一個(gè)對(duì)象的狀態(tài),然后才讓它去工作。而應(yīng)該告之對(duì)象如何去工作。這就意味著之前所有的那些If例子應(yīng)該變?yōu)椋?/span>
    mobile.alert();

    mobile.registerGasReading();

    mobile.sendTextMessage();

    mobile.notifyLocation();
    現(xiàn)假設(shè)遍布該程序中的一些If語(yǔ)句塊有重復(fù)的實(shí)現(xiàn)。在"重量級(jí)If"版本的程序中,可能很難發(fā)現(xiàn)它們;但在"告之而非問(wèn)之"版本的程序中,所有的實(shí)現(xiàn)都在Mobile中。所有的實(shí)現(xiàn)都在一處,這就便于察覺(jué)并根除問(wèn)題。
        傾聽(tīng)你的測(cè)試程序也能幫助你保持代碼的簡(jiǎn)潔。

    public interface Alarm {
      
    void alert(Mobile mobile);
    }

    public class Siren implements Alarm {
      
    public void alert(Mobile mobile) {
        
    if (mobile.getType == MobileTypes.STANDARD) {
          soundSiren();
        }
      }
    }

    public class TestSiren extends TestCase {
      
    public void test_alert() {
        LocationMobile mobile 
    = new LocationMobile();
        Siren siren 
    = new Siren();
        siren.alert(mobile);
        
    assert(sirenSounded());
      }
    }
    如果你密切地傾聽(tīng)測(cè)試程序,它可能會(huì)問(wèn)你,"為什么你需要一個(gè)LocationMobile去測(cè)試Siren呢?"的確,為什么呢?看起來(lái),Siren應(yīng)該還不知道LocationMobile吧。
    public class LocationMobile {
      
    private Alarm alarm;
      
    public LocationMobile(Alarm alarm) {
        
    this.alarm = alarm;
      }
      
    public void alert() {
        alarm.alert(); 
    // alert on Alarm no longer needs a mobile
      }
    }

    public class TestLocationMobile() extends TestCase {
      
    public void test_alert() {
        Alarm alarm 
    = EasyMock.createMock(Alarm.class);
        alarm.alert();
        EasyMock.replay(alarm);
        Mobile mobile 
    = new LocationMobile(alarm);
        mobile.alert();
        EasyMock.verify(alarm);
    }
    好像我只是交換了依賴關(guān)系。Alarm不再依賴Mobile,現(xiàn)在是Mobile依賴Alarm。但如果你仔細(xì)地觀察這個(gè)測(cè)試程序,你會(huì)發(fā)現(xiàn)真正的依賴關(guān)系是,Siren知曉了LocationMobile。一個(gè)具體類依賴另一個(gè)具體類,這違反了依賴反轉(zhuǎn)原則(DIP)。第二個(gè)例子就讓LocationMobile依賴Alarm接口。具體類依賴抽象,這就滿足DIP了。
        如果你使用TDD,并遵循簡(jiǎn)單法則和告之而非問(wèn)之原則去編寫(xiě)所有的代碼,你就處于成為一個(gè)更好的面向?qū)ο蟪绦騿T的道路上了。好的面向?qū)ο蟠a易于閱讀和維護(hù),但難以編寫(xiě),至少,在開(kāi)始時(shí)是這樣的。你寫(xiě)的越多,你就會(huì)變得越好,也會(huì)獲得更多的經(jīng)驗(yàn)。同時(shí),這些實(shí)踐經(jīng)驗(yàn)也會(huì)使你在自己的道路上受益匪淺。

    譯注
    [1]GodClass(上帝類)指包含了太多內(nèi)容的類。
    posted on 2008-10-07 17:06 John Jiang 閱讀(1874) 評(píng)論(7)  編輯  收藏 所屬分類: Java翻譯UnitTestMethodology

    評(píng)論

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-08 08:57 Jack.Wang
    very good, well done boy!  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-08 09:05 Sha Jiang
    Thanks :-  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-08 11:15 大衛(wèi)
    Thank you very much!  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-08 12:42 Sha Jiang
    @大衛(wèi)
    我對(duì)TDD也沒(méi)什么研究,興趣倒是有一些。
    但在實(shí)際的工作中,我沒(méi)有應(yīng)用過(guò)TDD,只是使用過(guò)單元測(cè)試罷了。  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-10 15:37 戰(zhàn)爭(zhēng)與和平
    實(shí)話實(shí)說(shuō),沒(méi)太明白。
    1. 告之而非問(wèn)之:不用if怎么進(jìn)行流程控制?
    2. 交換依賴關(guān)系的描述明白,不過(guò)例子不甚明白。  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-11 10:09 大衛(wèi)
    @戰(zhàn)爭(zhēng)與和平
    其實(shí)就是一個(gè)再封裝的問(wèn)題,將復(fù)雜的東西封裝起來(lái)。簡(jiǎn)化上層邏輯并使之清晰。  回復(fù)  更多評(píng)論
      

    # re: 編寫(xiě)好的面向?qū)ο蟠a(譯) 2008-10-19 15:02 謝亞力·帕它
    活著正好
      回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 黄色成人网站免费无码av| 精品亚洲视频在线观看| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 亚洲三级高清免费| 亚洲AV电影天堂男人的天堂| 亚洲人成网站在线观看青青| 一级毛片免费毛片一级毛片免费 | 久久99久久成人免费播放| 亚洲激情在线观看| 国产成人免费a在线视频app| 国产精品免费福利久久| 亚洲精品无码成人片久久不卡| 亚洲精品乱码久久久久久久久久久久 | 美女免费精品高清毛片在线视| 久久国产亚洲电影天堂| 热99re久久免费视精品频软件| 男女午夜24式免费视频| 麻豆亚洲AV成人无码久久精品 | 高清永久免费观看| 最新亚洲春色Av无码专区| 亚洲人成网77777色在线播放 | 亚洲欧洲日本天天堂在线观看| 午夜国产大片免费观看| 18禁黄网站禁片免费观看不卡| 特a级免费高清黄色片| 亚洲影视自拍揄拍愉拍| 亚洲成A∨人片在线观看不卡| 香蕉视频在线观看免费国产婷婷| 日本免费在线中文字幕| 九九九精品视频免费| 亚洲剧情在线观看| 亚洲国产成人久久综合一 | 久久久久亚洲av毛片大| 国产成人免费全部网站| 免费国产成人高清在线观看网站| 中国极品美軳免费观看| 高清免费久久午夜精品| 亚洲AV无码国产剧情| 国产亚洲福利在线视频| 亚洲免费在线视频播放| 91亚洲一区二区在线观看不卡|