假设我有这个:
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:认为这应该是社区维基?我没有足够的许可。 :/
答案 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交谈?