2012-02-06 72 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