执行以下操作的最佳方法是:
我有一个A类,它创建并保存来自B类的对象.B类的对象正在做自己的事情,有时他必须调用父对象(A类)的方法。我听说在对象B中保存对象A的引用并不是最好的想法(想法显示在代码片段中)。
Class A{
private B objectB;
public A(){
objectB = new B(this);
}
public void methodA(){
// [...]
}
}
Class B{
private A objectA;
public B(A objectA){
this.objectA = objectA;
}
public void methodB(){
// [...] do some stuff
objectA.methodA();
}
}
这样做真的很糟糕吗?还有更好的方法吗?
答案 0 :(得分:0)
据我所知,你的B类就像是一种代理或装饰,不同的是A和B不共享任何共同的界面。如果你的设计需要B类这样做(代理,装饰,......),最好的方法是定义一个通用的界面:B实现了A的界面,并且可以“模仿”"它:在这些情况下,共享对"代理"的引用上课还不错,实际上是必需的。 E.g:
public interface A {
void methodA();
}
public class AImpl implements A {
@Override
public void methodA() { /* .... */ }
}
public class AProxy implements A {
private final A a; // Use the interface not the implementation
public AProxy(final A a) { this.a = a; }
@Override
public void methodA() {
/* .... */
a.methodA();
/* .... */
}
}
另一种方法是定义一个层次结构,其中A是B的父级,因此B"需要"了解A工作,或相反A和B具有1对1 E-R依赖:您可以遵循复合设计模式 - 主要是在ORM技术上滥用 - 或依赖注入模式。在ORM技术中,父母和孩子总是互相参照,但他们彼此独立行事。
// It might be an @Entity
public class A {
private B child;
/* setter and getter */
}
// It might be an @Entity
public class B {
private A parent;
/* setter and getter */
}
在依赖注入中,您可以选择使用具有私有final字段及其构造函数参数的类(或多或少地执行此操作)或使用私有字段及其setter来强制执行此关系。
public interface A {
void methodA();
}
public class AImpl implements A {
@Override
void methodA() { /* .... */ }
}
public class B { // B does not implement A!
private final A a; // Use the interface not the implementation
public B(final A a) { this.a = a; }
public void methodB() { /* ... */ }
}
或
public class B { // B does not implement A!
private A a; // Use the interface not the implementation and it is not final
/* setter and getter */
}
共享父/外部对象的引用并不是一个问题,但这取决于您的设计需要什么,并且您必须相应地为您的应用程序建模。在我的第一个例子中,B实现了A接口,B 行为就像A一样,而后者B没有实现A接口而依赖于 A:有微妙但重要的区别。