mch*_*ctt 5 java dependencies class
说我有班级签名
Class1(Class2 c);
Class2(Class1 c);
Run Code Online (Sandbox Code Playgroud)
我如何初始化两者?
对于其中一个类,您不在构造函数中提供引用,但可以使用set-method.当它们之前都不存在时,初始化它们都依赖于彼此似乎是困难的.
class Foo {
private Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
}
class Bar {
private Foo foo;
setFoo(Foo foo) {
this.foo = foo;
}
}
Bar bar = new Bar();
Foo foo = new Foo(bar);
bar.setFoo(foo);
Run Code Online (Sandbox Code Playgroud)
另请注意,可能有更好的解决方案.比如使用Observer-pattern,一切都取决于你计划如何使用你的对象.
你的问题没有多大意义.如果每个类都需要另一个类进行初始化,那么您必须首先重新思考类的设计方式.
您可以考虑让其中一个类本身创建另一个类,而不必在构造函数中指定它.例如 :
class Class1 {
private Class2 c2;
public Class1() {
this.c2 = new Class2(this);
}
}
class Class2 {
private Class1 c1;
public Class2(Class1 c) {
this.c1 = c;
}
}
Run Code Online (Sandbox Code Playgroud)
或者创建setter并允许它们以"未初始化"状态创建(如果设置不正确,可能会抛出异常).例如 :
class Class1 {
private Class2 c2;
public void setClass2(Class2 c) {
this.c2 = c;
}
public void doSomething() {
if (null == c2) throw new IllegalStateException();
// ...
}
}
class Class2 {
private Class1 c1;
public void setClass1(Class1 c) {
this.c1 = c;
}
public void doSomething() {
if (null == c1) throw new IllegalStateException();
// ...
}
}
// somewhere else....
Class1 c1 = new Class1();
Class2 c2 = new Class2();
c1.setClass2(c2);
c2.setClass1(c1);
Run Code Online (Sandbox Code Playgroud)
此外,如果每个实例需要彼此双链接,您应该检查它们确实由正确的对象拥有,否则您可能会创建错误的引用...这正是为什么它在第一个中是一个糟糕的设计地点.考虑一下:
Class2 c2 = new Class2(new Class1());
Run Code Online (Sandbox Code Playgroud)
然而,你可能认为它是一个聪明的结构c2.getClass1().getClass2() != c2.
c1.getClass2() == c2 && c2.getClass1() == c1在上述两种情况下,它也都不能保证.
你的类应该检查后面的引用是否正确,并且你无法使用任何一种方法正确实现这一点!
要解决这个鸡和鸡蛋的问题,你需要某种工厂方法,或者第三类.考虑一下:
abstract class Class1 {
public abstract Class2 getClass2();
}
abstract class Class2 {
public abstract Class1 getClass1();
}
public Class3 {
private Class1 c1;
private Class2 c2;
public Class3() {
c1 = new Class1_Impl();
c2 = new Class2_Impl();
}
public Class1 getClass1() { return c1; }
public Class2 getClass2() { return c2; }
private class Class1_Impl extends Class1 {
public Class1 getClass2() { return c2; }
}
private class Class2_Impl extends Class2 {
public Class1 getClass1() { return c1; }
}
}
// and later on...
Class3 c3 = new Class3();
Class1 c1 = c3.getClass1();
Class2 c2 = c3.getClass2();
Run Code Online (Sandbox Code Playgroud)
有了这个,你c1.getClass2() == c2 && c2.getClass1() == c1永远保证.
如果你还在读书,那么你就是在启蒙的轨道上.如果您可以看到此类设计的后果,那么您将了解循环依赖是如何反模式的,应该避免.
但是,您的问题不够具体,我无法全面为您提供更合适的方式以更干净,更好的方式解决您的问题.