2009-12-30 48 views
4

在值對象上使用方法鏈接模式(比如返回一個新的對象而不是這個)是可以接受/好的做法嗎?那裏有解決方案實施的案例嗎?用值對象鏈接方法

我想不出任何缺點,但我想聽聽你的觀點。

+0

我提交你的審查,[權威方法鏈決策樹](http://chat.stackoverflow.com/transcript/message/4316194#4316194) – rdlowrey 2012-08-15 06:31:20

回答

5

結論:這種做法是完全可以接受的。

我相信這通常是當你有一個不可變的對象時發生的。不是改變原來的對象,而是用給定的值創建一個新的對象並返回。使用方法鏈接進行和反對的參數與使用可變對象和不可變對象大致相同。

我唯一擔心的是,這對於班級的調用者來說很清楚 - 他們不能依賴與鏈接對象的身份相等性,並且必須明確調用不會改變原始對象。雖然如果他們實際上是串聯電話,他們不會分配中介對象,所以不會有很大的風險。重要的是它們只用使用方法鏈中的最後一個對象。

要使用java.lang.String中作爲一個例子,字符串的客戶這樣做:

myString.trim().replace("a", "b").substring(3, 9); 

...沒什麼意思,和通常表示程序員的誤解。他們應該做的是:

String myNewString = myString.trim().replace("a", "b").substring(3, 9); 

...然後在後續操作中使用myNewString。有趣的是,Java,Findbugs的靜態分析工具可以檢測到這種誤解的實例,並將其報告爲可能的錯誤。

客戶理解是主要案例。其他缺點包括,如果價值對象的創建非常昂貴,那麼在每條鏈上創建一個新對象將會帶來性能上的衝擊。如果這可能是一個問題,你應該能夠從你自己的情況中看出來。在這種情況下,您可能需要實現Builder模式,而不是在每個方法鏈上創建新對象。

除了這些,我想不出任何其他問題。

2

大量的java類提供了不可變的值對象。 java.lang.String,java.math.BigInteger和java.math.BigDecimal是不可變的值對象,它們的方法返回一個新的對象。最大的缺點是人們對它並不瞭解,它不可改變,並認爲他們正在改變原創。

有些語言比其他語言更強調不變性。在Ruby中,字符串是可變的,並且集合通常提供一個返回副本的版本和另一個改變現有副本的版本(例如Array#sort和Array#sort!)。在Clojure中,不變性是常態。

2

是的,這是一件非常好的事情。例子:

  • 字符串在Java和.NET
  • DateTimeTimeSpan英寸NET
  • 許多類型中Joda TimeNoda Time
  • 解釋功能性的語言,如F#

對於引用類型,其被實現爲不可變值對象,其缺點有時會你最終產生了大量的垃圾。在任何一種情況下,您的都可以通過結束大量複製 - 但這取決於具體情況。