我应该为可以从另一个参数查询的对象添加方法/构造函数参数

时间:2011-03-13 16:30:07

标签: java

假设我有这个:

public class A {
   private B b;

   public B getB() {
     return b;
   }
}

现在,我有一个需要A和B的类。问题是,如果构造函数只接受A,然后我会从A查询B,或者构造函数是否要求A 和< / strong> B?

应该是这样的:

public MyClass(A a) {
  this.a = a;
  this.b = a.getB();
}

或者这个:

public MyClass(A a, B b) {
  this.a = a;
  this.b = b;
}
p / s:我认为这是一个相当无聊的问题,但无论如何。

p / p / s:认为这应该是社区维基?我没有足够的许可。 :/

7 个答案:

答案 0 :(得分:2)

我认为这是一个很好的问题!因为好的做法存在“矛盾”。

第一个解决方案应用规则:“尝试将最少数量的参数传递给方法(或构造函数)”(Robert C martin在他的书“清洁代码”中提到这条规则)

第二个片段遵循Law of Demeter的规则,该规则说MyClass应该尽可能少地了解A。

就个人而言,我会选择第二种选择,但在某些情况下,我可能会选择第一种选择。

答案 1 :(得分:1)

第二个选项允许用户使用非相关B调用MyClass:

new MyClass(new A(),new B());

虽然第一个选项确保MyClass使用相同的B ...
因此,这取决于您的需要,这是首选。

答案 2 :(得分:1)

在A类和B类可能是子类的情况下,在MyClass中始终使用与使用的特定A子类相对应的B子类可能非常重要。如果需要为特定A实例正确配置B实例,即使没有子类化,类似的注意事项也适用。在类A的定义中添加getB()方法是帮助满足此类需求的几种设计模式的一部分。在这些情况下,MyClass构造函数应该只接受A的实例并从A中检索正确的B实例。

如果MyClass可以为任何特定的A实例使用一系列B实例,那么双参数构造函数更有意义。这将生成与任何特定A实例一起使用的B实例的任务转移到创建MyClass实例的任何客户端类。对于各种混合和匹配类型的结构而言,这可能是正确的解决方案。但这一切都引出了一个问题:为什么A类首先采用getB()方法?

答案 3 :(得分:0)

这取决于,如果您有类似以下的内容,那么让Car仅将Engine作为构造函数参数,因为它可以说engine.getEngineParts()

class Car
class Engine
class EnginePart

如果合约较弱,我建议使用setter注入并使用默认构造函数。

如果您按如下方式创建构造函数,则无法确定EnginePart实际属于Engine。例如,当你想EnginePart 添加到Engine时,例如

,这可能是偶然的。
EngineAssembler (Engine engine, EnginePart part) {
    engine.addPart(part);
}

答案 4 :(得分:0)

这取决于问题。 这取决于A和B是什么。

无论如何,我选择带有A作为参数的构造函数(即使你的问题太通用了)

答案 5 :(得分:0)

最好的方法是在创建对象A时,通过setter或构造函数设置B的值,并将A对象传递给新类。

public class MyClass{
  A a;
  Myclass(A a){
  this.a = a;
}

public void doSomething()
{
System.out.println(a.getB());
}
}

MyClass始终只能使用一个实例变量。因为你总是可以用a.getB()获得B.如果B不能为空,请确保在对B进行操作时检查B的空值。

答案 6 :(得分:0)

是否有可能根本不通过B,而是在需要B做某事时让MyClass与A交谈?