2012-02-06 73 views
1

最合適的地方因此,假如我們有Foo類具有屬性FirstProp和SecondProp和ThirdProp。 商業上,SecondProp中允許的值取決於爲FirstProp設置的值,ThirdProp允許的值取決於FirstProp和SecondProp的值。 最適合放這個邏輯的地方在哪裏?物體狀態驗證

如果是在每個setter方法再有就是事實級用戶可以設置他的另外兩個之前ThirdProp,將我們還需要強制設置的屬性然後順序?這看起來並不理想。此外,如果我們要將對象的初始化限制在parmererized構造函數中,那麼當我們將對象設計爲值類型(結構體)時,由於結構體中的默認構造函數始終可用,因此這將不實用。

理解的任何輸入。

回答

0

就個人而言,我會保持美孚作爲一個純粹的Java bean。這有很多好處,一開始可能並不明顯。其中之一是你需要/想要一個簡單的setter當你讀/持久這個對象到數據庫(如果你是)。

相反,創建富的一個子類,其中包含業務邏輯。這會將你的代碼分離成一個持久層和一個域/業務對象層。

+0

如果我只是正確理解你,那麼在更具體的類中進行這種檢查就會違反LSP。考慮經典的矩形<-->平方的例子 – 2012-02-06 04:09:02

+0

這是真的,取決於他的邏輯,它可能是LSP的違規。他的榜樣確實很難確定。 – Michael 2012-02-06 12:59:28

0

我寧願讓Foo一個不變的值對象,使所有必要的檢查靜態工廠。

final class Foo { 
    private final SomeObject first; 
    private final SomeObject second; 
    private final SomeObject third; 

    private Foo(SomeObject first, SomeObject second, SomeObject third) { 
    this.first = first; 
    this.second = second; 
    this.third = third; 
    } 

    /* Simple Getters + equals and hashCode if necessary */ 

    public static Foo newInstance(SomeObject first, SomeObject second, SomeObject third) { 
    if (! /* your condition holds */) 
     throw new IllegalArgumentException(); 

    return new Foo(...); 
    } 
} 
+0

但是,這種方法是否真的阻止了類用戶跳過工廠並直接進入構造函數? – MSD 2012-02-06 23:55:31

+0

@MSD,構造函數是私有的,它強制用戶使用靜態工廠。你可以創建這樣的對象並自己嘗試。無論如何,所有這些限制都可以在下層(任何方法)避免。 – 2012-02-07 15:25:44

0

我最好組中的validate()方法的屬性的驗證,可以既可以使用對象(如果正確初始化返回true)之前外部調用,或者任何吸氣劑內拋出InvalidObjectStateException如果使用它們在屬性設置正確之前。

+0

我不同意。絕不允許該對象進入無效狀態。 – cdaq 2013-08-14 18:35:26