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

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

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

    隨筆 - 17  文章 - 49  trackbacks - 0
    <2006年8月>
    303112345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    常用鏈接

    留言簿(1)

    隨筆分類(17)

    隨筆檔案(17)

    相冊

    最新隨筆

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    2006 8 30 星期三

    談優先選擇不變類

    不變類就是實例不能被改變的類, Effective Java Item13 詳細的探討了為什么設計中要優先考慮將一個類設計為不變的,在細讀后感覺平時自己的設計和這個觀念有比較大的溝壑,值得總結一下這個 item ,并反思一下如何去實踐這個 best practice

    不變類的優點有如下幾個:容易設計,實現和使用,不易出錯,安全性更好。

    不變類很簡單,它只會有一個狀態,所以一旦在實例化的時候保證了這個不變實例復合某些業務邏輯上的要求,它就會一直,保持這些要求和規約得到滿足。而一個可變類,則相對來說不可靠得多。

    不變類是線程安全的,不需要考慮同步的問題,可以安全地共享。同時也不需要在共享過程中的傳遞引用環節使用“防御性復制”( item24 詳談,主要是保持數據的復制而不是引用的復制)。

    由于不變類的上述優點,使得它非常適合成為其他類的組成部分,如果你明確了一個組件是不變類,則能在維護整體的業務邏輯穩定性方面輕松很多。非常顯著的一個例子就是用于 map keys set elements 時,不變類的穩定性保證了數據不會不小心被改變。反之,如果是用可變類, key 對象的一次邏輯上不恰當的變動(語法上無錯,可以通過編譯)可能導致另一處代碼在 map 中獲取 elements 時找到不正確的值,而實際經驗中,我們深刻體會到的一件事情就是不被編譯器發現而且不拋出異常的程序錯誤往往會浪費極大的精力,而且要靠好的視力和豐富的調試經驗才能發現。

    不變類的唯一缺點就是對應每個不同的值,必須存在一個單獨的實例。當需要頻繁變更值的時候,性能大為降低,典型的例子就是拿著 String 來反復折騰,而不用 StringBuffer 。而 StringBuffer 正是用來解決這一缺點的,當一個不變類可能需要頻繁改變值的時候,就需要設計這么一個對應的可變類來暫時替身。

    那么怎么在實際設計中貫徹這種優先選擇不變類的思想呢,總的原則就是:除非你找到非常好的理由來設計為一個可變類,否則就應該設計為不變類,要有意的抵抗為每個變量配上 getter setter 的沖動,當然我不是在說你要違反 javabean 的基本要求。。。基本上,小的存放數值的對象都應該設計為不變類,如果該類的值經常改,就配上對應的可變類。而總有些類顯然不可能是不變類的,這時也要盡可能的限制它的可變性。類的構造器應該實例化一個充分滿足邏輯不變式的實例,而不要交出一個半成品,也不應該提供構造器之外的一個所謂的初始化方法,除非是有極好的理由。同理,也不要提供“重設初始化”方法以達到實例復用的目的,比起它帶來的危害,這個垃圾回收環保復用的思路帶來的性能提升實在微不足道。

    ?

    最后,歸納一下設計不變類的 5 條規則:

    1. ????? 不提供任何修改對象的方法。

    2. ????? 保證沒有任何一個方法會被覆蓋。

    3. ????? 所有的域都是 final 的。

    4. ????? 所有的域都是 private 的。

    5. ????? 如果不變類內部包括可變的子對象,保證它絕對不會被其他代碼獲取引用。

    ?

    要解釋的是第 5 ,第 4 點并不能保證這一點,要做到第 5 點,就必須注意在不變類的實例化中,決不通過其他代碼提供的引用來賦值給這個子對象,也決不提供這個子對象的引用的獲取方法,因為這些傳入傳出的引用在別的代碼中可以被用來修改對象的域。在構造器,讀取方法中使用防御性復制,只傳值,不傳引用。而且是遞歸性的防御性復制,關于這一話題,在以后的隨筆中再詳細探討。

    好了,這一篇就到這里,我從中學到的東西,總結起來一句話,就是要非常吝嗇類的可變性,從而獲取堅固,不易錯的類結構。

    ?

    ?

    ?

    Wednesday, August 30, 2006

    Talk about favoring immutability

    Immutable class is the class whose instance can not be modify. Item 13 for Effective Java discussed in detail about why one should favor it rather than a mutable class. I felt that my own designing in practice defers from the idea quite a lot, so it is worthwhile to summary this topic and ponder how to implement this best practice.

    Immutable class has several merits: easy to design, implement and use, less prone to error and better safety.

    Immutable class is simple, it only have exactly one state, once the invariant has been established at the time it was initialized, these invariant can be guaranteed for all time. It is more reliable than mutable class.

    It is thread safe, synchronization consideration can be omitted and it can be shared freely. You don’t have to make defense copy when sharing it. (Item 24 take about defensive copy, main idea is copying values instead of reference of objects.)

    These qualities makes immutable class excellent as building block of other class. It is much easier to maintain the invariant of a class when you know that the underlying components are immutable classes. Especially using in keys of a map and elements of a set, once they are put into map or set, their immutability guaranteed the data will stay correct. On the contrary, if in the case of mutable class, a logically incorrect evaluation of a key object (which is correct in syntax, compilable) may cause an getObject() from another place gets a incorrect value, and we deeply aware of that the fact a error that neither discoverable in compile time nor throwing a exception, is extremely time wasting to find out, sometimes it is all about good eyesight and skilled debug techniques.

    The only disadvantage of immutable class is that for every distinct value, it has to have a separate object, frequent operations that create new objects will harm the performance. The most familiar example is String is used to do lots of modification, while leaving StringBuffer alone. While StringBuffer is the very solution for the very problem, when a mutable class has to be changing value a lot, a companion modifiable class shall be provided.

    Then how we can implement the idea into actual design? The key point is to make it a immutable class unless you find a good reason to make it mutable one. Try to resist the impulse to provide setter along with getter when designing a field, well, I am not asking you to violate the basic rule of javabean…basically, small value objects shall be immutable. Provide companion class when it needs to be change a lot. There are some class that immutable is impossible, then try to limit the mutability of them. Constructor shall initial the object fully with invariants fulfilled, don’t initial partly and then making a “initial method” with it. For the same reason, never provide a so called “reinitial method”, it brings little if any performance benefit at the cost of increased complexity.? ?

    For the last thing, these are 5 rules for making a class immutable:

    1. Don't provide any methods that modify the object (known as mutators).

    2. Ensure that no methods may be overridden.

    3. Make all fields final.

    4. Make all fields private.

    5. Ensure exclusive access to any mutable components.

    ?

    No.5 shall be explained a little bit, notice that No.4 doesn’t ensure it. To achieve No.5, it have to avoid using reference from other objects when initialing a internal mutable object, and never provide accessor to these objects, because reference passed inward or outward can be used to modify these objects. Use defensive copy in constructors and accessors.

    And that’s all of it, what I have learn can be summarized into one sentence: be niggardly when designing the mutability of a class, it brings back rigidity and less error prone structure.

    posted on 2006-08-30 21:11 Ye Yiliang 閱讀(1418) 評論(4)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: 談優先選擇不變類 2006-08-30 21:56 hsp
    在Tester-Doer時,immutable 類型體現其價值.
    確保thread-safe.

    這個問題在C#中delegate也是類似的.
    因此delegate也是immutable
    可用上面類似的thread-safe方法來raise .但C#編譯器自動將其inline
    .這還需要我們使用Attribute來禁止編譯器做的"好事"
    delegate void handler();
    handler realHandler=delegate(){...};
    ..........

    handler tempHandler;
    tempHandler=realHandler;
    if(tempHandler!=null) tempHandler();  回復  更多評論
      
    # re: 談優先選擇不變類 2006-08-31 14:15 dylan
    跟ioc有沖突,感覺有點落伍了  回復  更多評論
      
    # re: 談優先選擇不變類 2006-08-31 15:26 hsp
    to dylan
    跟IOC的沖突也并非完全有問題
    如果IOC容器支持 構造函數注入 ,那么不變類在IOC中還是有生存空間的.  回復  更多評論
      
    # re: 談優先選擇不變類 2006-09-06 11:48 hsp
    YYL的下一篇文章遙遙無期~~~~~~~~~~~~~~~:D  回復  更多評論
      
    主站蜘蛛池模板: 国产在线98福利播放视频免费| 国产亚洲无线码一区二区| 精品一区二区三区无码免费直播| 亚洲精品国产精品乱码不卞| 女人隐私秘视频黄www免费| 亚洲天堂一区二区三区| 国产精品99久久免费| 日韩视频在线观看免费| 十八禁的黄污污免费网站| 亚洲av无码无在线观看红杏| 免费无码肉片在线观看| 久久www免费人成精品香蕉 | 国产色在线|亚洲| 亚洲福利在线播放| 222www免费视频| jizz日本免费| 精品国产成人亚洲午夜福利| 国产亚洲精品成人AA片新蒲金 | 亚洲AV无码国产丝袜在线观看| 韩国欧洲一级毛片免费| 一级成人a毛片免费播放| 久久精品国产亚洲av天美18| 野花高清在线观看免费3中文 | 国产亚洲精品国看不卡| 无人影院手机版在线观看免费| 精品免费久久久久国产一区| 久久久久亚洲国产| 久久久久亚洲av无码专区蜜芽 | 久久亚洲精品无码VA大香大香| 亚洲?V乱码久久精品蜜桃 | 国产三级在线观看免费| 中文字幕乱码一区二区免费| 自拍偷自拍亚洲精品播放| 亚洲午夜久久久久久尤物| 久久亚洲国产精品一区二区| www.亚洲色图| 国产麻豆剧传媒精品国产免费| 8x网站免费入口在线观看| 三年片在线观看免费| 香蕉国产在线观看免费| 国产精品手机在线亚洲|