如何在Java中初始化依赖于彼此的类?

mch*_*ctt 5 java dependencies class

说我有班级签名

Class1(Class2 c);
Class2(Class1 c);
Run Code Online (Sandbox Code Playgroud)

我如何初始化两者?

Sim*_*erg 7

对于其中一个类,您不在构造函数中提供引用,但可以使用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,一切都取决于你计划如何使用你的对象.


Yan*_*hon 5

你的问题没有多大意义.如果每个类都需要另一个类进行初始化,那么您必须首先重新思考类的设计方式.

您可以考虑让其中一个类本身创建另一个类,而不必在构造函数中指定它.例如 :

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永远保证.


如果你还在读书,那么你就是在启蒙的轨道上.如果您可以看到此类设计的后果,那么您将了解循环依赖是如何反模式的,应该避免.

但是,您的问题不够具体,我无法全面为您提供更合适的方式以更干净,更好的方式解决您的问题.