<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 閱讀(1412) 評論(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  回復  更多評論
      
    主站蜘蛛池模板: 精品国产污污免费网站| 免费一级毛片在线播放视频免费观看永久 | 33333在线亚洲| 亚洲国产精品一区二区久久hs| 久久精品亚洲中文字幕无码麻豆| 久久最新免费视频| 在线观看亚洲成人| 中文在线免费观看| 亚洲va中文字幕无码久久| 野花香在线视频免费观看大全| 亚洲成av人片天堂网| 三年片在线观看免费观看大全动漫 | 久久久亚洲欧洲日产国码二区| 一个人免费视频在线观看www| 亚洲AV无码一区二区二三区软件 | 亚洲成人高清在线观看| 免费国产作爱视频网站| 亚洲欧美精品午睡沙发| 四虎免费永久在线播放| 国产免费伦精品一区二区三区 | 亚洲三级视频在线观看 | 国产亚洲精品AA片在线观看不加载 | 亚洲精品一级无码鲁丝片| 三上悠亚在线观看免费| 久久亚洲AV成人无码国产| 在线观看无码的免费网站| 四虎成人精品国产永久免费无码| 亚洲色欲久久久综合网| 1a级毛片免费观看| 豆国产96在线|亚洲| 亚洲精品蜜桃久久久久久| 国产精彩免费视频| 国产精品亚洲一区二区三区久久 | 亚洲av成本人无码网站| 亚洲色WWW成人永久网址| 中国xxxxx高清免费看视频| 亚洲AV日韩AV一区二区三曲| 亚洲香蕉网久久综合影视| 精品免费人成视频app| 国产青草亚洲香蕉精品久久| 久久青青成人亚洲精品|