2010-09-02 53 views
6

所以我一直在閱讀Joshua Bloch的Effective Java,並注意到我在工作中實際遇到的兩點。不變性和可讀性

Point 1:使setter方法使代碼更具可讀性。 在他的例子中,我們有一個帶有可笑的巨大構造函數的類。當人們實例化課堂時,很難說出所有參數的情況。因此,他建議製作簡約構造並具有用於所有其他選項設置方法,所以不是...

MyClass的clazz所=新MyClass的(A,B,C, d,E,F,G) ;

你會寫....

MyClass的clazz所=新MyClass的(A,B, C);
clazz.setDitto(d);
clazz.setEcho(e);
clazz.setFunzies(f);
clazz.setGumballs(g);

其中,作爲一個可讀代碼的巨大支持者,我非常喜歡。

第2點:一般來說,他建議有不可變的類。他深入探討了爲什麼不可變類比擁有可能處於幾個不同狀態的類要好得多。我可以肯定地說,他把這個想法賣給了我,我迫不及待地想寫出大部分我從現在開始寫下來的類,除了不可變,除了......

當你有一個巨大的構造函數的不可變類時會發生什麼?你不能爲它設置setter方法;那會破壞不變性。我嘗試瀏覽本書的其餘部分,但我不認爲他爲此提供瞭解決方案。

有一種可能性使一次性使用setter方法,但只是一個setter方法可用於一個被認爲是不可變性的類令人沮喪的事實,即使它只是拋出一個異常如果你隨後嘗試它倍。

有沒有人有如何處理這個問題的好主意?我目前正在面對這個問題,在那裏我有一個不可變類,帶有一個巨大的構造函數,我想重構一些更具可讀性而又不破壞不變性的東西。

+0

這似乎是一個有用的概念將有一個可變的和不可變的類派生自一個共同的抽象基地(它宣佈所有屬性的getters)。不可變類的構造函數可以接受基類的參數。不知道如何讓可變類使用讀寫屬性來影響抽象的只讀屬性,但是不需要創建實現只讀屬性的中間類。 – supercat 2010-09-02 23:30:18

回答

14

一種選擇是提供一個單獨的構建器類,它提供了構造器,它負責構造實際的對象。

在Bloch的「Effective Java」的第二版中,第2項說明了這一點對於不可變類。主要想法是:

  • 構建器對每個選項都有一個可變字段。
  • 構建器將本身作爲單個參數傳遞給不可變類的構造函數。
+1

+1在我看來,使用可鏈式方法的構建器實際上可以通過'void'設置方法提高可變對象的可讀性。 – ColinD 2010-09-02 22:26:40

+0

同意。 Bloch在上面提到的示例生成器中包含可鏈接的setter。 – 2010-09-02 22:36:07

+0

太棒了!我不能相信我錯過了這一點。我大部分時間都在瀏覽不變性部分,完全忘記檢查構造函數。 – Noj 2010-09-02 23:07:12

3

Introduce Parameter Object,也許?它有助於解決問題,但可能是有用的。你的參數對象不需要任何方法;它只是保存這些數據,然後設置它,而不是真正的課程。然後你的真實類通過參數對象在構造函數中初始化自己。

0

如何具有支持干將的抽象基類但沒有etters爲類的所有屬性,派生密封的「不可變」的類,其構造函數接受基類對象,派生的可變類包括所有屬性的setter?