抽象的initialize()方法而不是依赖注入,良好的做法?

时间:2012-11-13 20:36:32

标签: java oop dependency-injection initialization abstract-class

这是我正在设计的一个简化示例。

public class ExampleManager {

    private Foo foo;
    private ArrayList<Example> examples;
    ...

    public ExampleManager() {
        this.foo = new Foo();
        this.examples = new ArrayList<Example>();
    }

    public void add(Example e) {
        examples.add(e);
    }

    public void doSomethingWithExamples() {
        for (int i = 0; i < examples.size(); i++) {
            examples.get(i).doSomething();
        }
    }
    ...
}

public abstract class Example {
    private Foo foo;

    public Example(Foo foo) {
        this.foo = foo;
    }
    ...
}

为了使用该库,我必须扩展Example类并向ExampleManager添加示例,它应该是修改Example个对象的唯一类。 所以我有这个Example1类:

public class Example1 extends Example {

    public Example1(Foo foo) {
        super(foo);
    }
    ...
}

我目前正在这样初始化经理:

ExampleManager manager = new ExampleManager();
Example1 example1 = new Example1(manager.getFoo());
manager.add(example1);

我的Example需要Foo对象,但我想知道我是否可以删除Example1构造函数中的Foo参数,所以如果有人使用该库,不必调用manager.getFoo()来创建示例 我正在考虑以下解决方案,它将隐藏Foo初始化,因此使用该库的人只需要实现initialize(Foo)方法,而Foo将是将示例添加到ExampleManager)时自动初始化 在ExampleManager中:更改add(Example)方法:

public void add(Example e) {
    e.initialize(foo);
    examples.add(e);
}

Example中,初始化(Foo foo);将是一个抽象的方法,所以在Example1我会有这样的东西:

@Override
public void initialize(Foo foo) {
    this.foo = foo;
}

有没有更好的方法呢?

1 个答案:

答案 0 :(得分:1)

在我看来,如果你需要像你描述的那样处理物体,你首先会遇到OO模型的一些问题。 - 或许你的示例代码没有揭示真实的事情。

特别是

  

ExampleManager [...]应该是修改Foo对象的唯一类

  

Example需要Foo对象

看起来有些'特别'。

您能详细说明ExampleManagerFoo实例之间以及ExampleFoo实例之间的互动吗?

好的,关于你的评论,我提出了观察者模式,就像你的initialize()方法一样:

public abstract class Example {
    protected Foo callbackHandler;

    public void setCallbackHandler( Foo handler ) {
        this.callbackHandler = handler;
    }

    protected void doCallback( SomeType event ) {
        if ( this.callbackHandler != null ) {
            this.callbackHandler.doYourThing( event );
        }
    }
}

并且在向对象添加对象时将ExampleManager注册为自身或其Foo实例作为回调处理程序。非抽象子类只需要在需要进行通信时调用doCallback(...),而不必处理回调的任何设置内容。