<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

       :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理 ::
      131 隨筆 :: 1 文章 :: 530 評論 :: 0 Trackbacks
    編寫好的面向對象代碼

        本文是java.net上的一篇博客,作者Curtis Cooley對編寫好的面向對象代碼有些建議,希望對大家都有所幫助。(2008.10.08最后更新)

    獲取經驗沒有捷徑。編寫好的面向對象代碼需要經驗,但這兒有三種做法能幫你在一開始就很順利,即便你是老頑固:
        1. 使用測試驅動開發(fā)(TDD)編寫你所有的代碼
        2. 遵循簡單法則
        3. 告之而非問之

    使用TDD編寫所有代碼
        按測試先行編寫的代碼與按測試后行編寫的代碼是極為不同的代碼。按測試先行編寫的代碼是松耦合與高聚合的。當某個屬性或私有方法需要暴露給測試程序時,按測試后行編寫的代碼常會打破封裝,因為該類并不是為了測試而設計的。如果你首先編寫測試代碼,你的依賴將會更好,你的代碼將是松耦合與高聚合的。后面會有更多關于測試能幫助你設計更佳代碼的內容。

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

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

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

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

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

    mobile.registerGasReading();

    mobile.sendTextMessage();

    mobile.notifyLocation();
    現(xiàn)假設遍布該程序中的一些If語句塊有重復的實現(xiàn)。在"重量級If"版本的程序中,可能很難發(fā)現(xiàn)它們;但在"告之而非問之"版本的程序中,所有的實現(xiàn)都在Mobile中。所有的實現(xià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());
      }
    }
    如果你密切地傾聽測試程序,它可能會問你,"為什么你需要一個LocationMobile去測試Siren呢?"的確,為什么呢?看起來,Siren應該還不知道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);
    }
    好像我只是交換了依賴關系。Alarm不再依賴Mobile,現(xiàn)在是Mobile依賴Alarm。但如果你仔細地觀察這個測試程序,你會發(fā)現(xiàn)真正的依賴關系是,Siren知曉了LocationMobile。一個具體類依賴另一個具體類,這違反了依賴反轉原則(DIP)。第二個例子就讓LocationMobile依賴Alarm接口。具體類依賴抽象,這就滿足DIP了。
        如果你使用TDD,并遵循簡單法則和告之而非問之原則去編寫所有的代碼,你就處于成為一個更好的面向對象程序員的道路上了。好的面向對象代碼易于閱讀和維護,但難以編寫,至少,在開始時是這樣的。你寫的越多,你就會變得越好,也會獲得更多的經驗。同時,這些實踐經驗也會使你在自己的道路上受益匪淺。

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

    評論

    # re: 編寫好的面向對象代碼(譯) 2008-10-08 08:57 Jack.Wang
    very good, well done boy!  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-08 09:05 Sha Jiang
    Thanks :-  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-08 11:15 大衛(wèi)
    Thank you very much!  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-08 12:42 Sha Jiang
    @大衛(wèi)
    我對TDD也沒什么研究,興趣倒是有一些。
    但在實際的工作中,我沒有應用過TDD,只是使用過單元測試罷了。  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-10 15:37 戰(zhàn)爭與和平
    實話實說,沒太明白。
    1. 告之而非問之:不用if怎么進行流程控制?
    2. 交換依賴關系的描述明白,不過例子不甚明白。  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-11 10:09 大衛(wèi)
    @戰(zhàn)爭與和平
    其實就是一個再封裝的問題,將復雜的東西封裝起來。簡化上層邏輯并使之清晰。  回復  更多評論
      

    # re: 編寫好的面向對象代碼(譯) 2008-10-19 15:02 謝亞力·帕它
    活著正好
      回復  更多評論
      

    主站蜘蛛池模板: 全黄大全大色全免费大片| 狼色精品人妻在线视频免费| 国产羞羞的视频在线观看免费| 亚洲av无码不卡私人影院| 亚洲av无码无线在线观看| 午夜成人免费视频| 日韩亚洲不卡在线视频中文字幕在线观看 | 日韩精品视频免费观看| 亚洲精品日韩一区二区小说| 国产香蕉九九久久精品免费| 亚洲色丰满少妇高潮18p| 蜜桃精品免费久久久久影院| 鲁死你资源站亚洲av| 亚洲精品成人久久久| A毛片毛片看免费| 亚洲av日韩av高潮潮喷无码 | 色www永久免费网站| 亚洲国产老鸭窝一区二区三区 | 国产va在线观看免费| 91亚洲视频在线观看| 女人18一级毛片免费观看| 无码色偷偷亚洲国内自拍| 亚洲欧洲中文日韩久久AV乱码| 东北美女野外bbwbbw免费| 亚洲丁香色婷婷综合欲色啪| 成人免费黄色网址| 亚洲av日韩综合一区二区三区| 亚洲一区二区三区在线视频| 少妇太爽了在线观看免费视频| 亚洲国产成人综合| 免费欧洲毛片A级视频无风险| 91福利免费网站在线观看| 亚洲欧洲日韩在线电影| 国产大片线上免费看| 爽爽爽爽爽爽爽成人免费观看| 亚洲国产午夜精品理论片| 免费a级毛片视频| 97视频免费观看2区| 亚洲AⅤ男人的天堂在线观看| 狠狠色伊人亚洲综合成人| 我要看WWW免费看插插视频|