2013-10-18 57 views
0

doJob()方法中,B通过getter来引用。我个人不赞成这个想法,宁愿只是b.execute(),因为我确信getB()将永远不会被修改。工程封装

我知道,通过这样做,会离开封装,但不是封装B对象在这里矫枉过正?

class A{ 
    private B b; 

    public void setB(B b){ 
     this.b = b; 
    } 

    public B getB(){ 
     return b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 
+1

在类内部,您不必担心使用'getB()',因为'b'是在您的类中定义的'private'变量。但是,一旦你尝试从另一个类访问它,你将需要使用getter。 – Bucket

+0

http://programmers.stackexchange.com/questions/181567/should-the-methods-of-a-class-call-its-own-getters-and-setters – Habib

+1

当你声明“*'getB()'会永远不要修改*“,通过在代码中写入”final“来强制执行。 – hyde

回答

3

难道真如属性仍然private不一样,如果你访问B通过它的属性,长吸气剂物质(所以是的,呼吁getB()是矫枉过正,它肯定不会打破任何的设计模式)。

1

只有当你让整个班级,或至少让制定者和获得者,final,这是正常的。

否则这打破:

class A2 extends A { 

    private B2 b; 

    @override 
    public void setB(B b){ 
     this.b = new B2(b); 
    } 

    @override 
    public B getB(){ 
     return b.toB(); 
    } 
} 

现在调用非重写doJob()会使用错误的成员变量。

3

在这种情况下,它可能是矫枉过正,因为它是一个简单的对象。但是,如果有懒加载和你的对象看起来是这样..

class A{ 
    private B b; 

    public void setB(B b){ 
     this.b = b; 
    } 

    public B getB(){ 
     this.b = this.b ?? new B(); 
     return this.b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 

那就不是矫枉过正通过属性来访问您的私有成员。

我不知道这是否会对你有帮助,但是如果B是一个依赖项,那么你的对象应该像这样设置,其中IB是具体对象B的接口。它是一个控制模式的反转,从A.对象B但是,这是矫枉过正简单对象图以及

class A{ 
    private IB b; 

    // Use inversion of control 
    public A(IB b){ 
     this.b = b; 
    } 

    public IB getB(){ 
     return this.b; 
    } 

    public void doJob(){ 
     getB().execute(); 
    } 
} 
+0

我发现这个懒惰的加载程序模式特别有用,当信息重新创建昂贵时,经常失效并偶尔使用。如果它失效,我只是翻转一个布尔值来表示它的脏,下一次它需要重新计算。但在此之前它可能会失效很多次,尽管如此,将所有这些unnsisary recalcs节省给我 –

+0

当创建对象时,它们应该是有效状态下99%的时间。尽管这是一个激烈的争论。我倾向于倾向于保持我的对象处于有效状态,但其他人则认为对象应该能够保存在无效状态。例如,如果用户正在填写用户配置文件,则他们应该能够将该用户配置文件保存在任何状态并在稍后继续。我认为,如果域模型暴露在客户端,他们的设计就有一个基本缺陷。有特殊的对象暴露给客户端(DTO或ViewModels)。 –

+0

我会说他们必须始终处于**外部**有效状态 –

1

提供了访问/ mutator方法的私有成员,可以添加错误检查,更换部件的存储,并做内部其他的事情去上课。你如何访问班上的成员是你的选择。

如果您发现以后需要更改类内部,则可以切换到访问器/增变器。当然,这个简单的例子不需要accessor(getter)方法。但要认识到,使用吸气剂可能会使更复杂的情况受益。

2

您正在通过使用吸气剂来降低风险。如果在一种使用情况下结果为Bnull,或者由于新要求您需要初始化B。该模式允许您更新getB(),而无需更改A中的任何其他内容。

public B getB(){ 
    if(b == null) { 
     b = getEntityManger().findB(); // or wherever you wanted to get B from 
    } 

    return b; 
}