【问题标题】:abstract initialize() method instead of dependency injection, good practice?抽象initialize()方法而不是依赖注入,好的做法?
【发布时间】:2012-11-13 20:36:32
【问题描述】:

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

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;
}

有没有更好的方法来做到这一点?

【问题讨论】:

  • 我只是浏览了一下...泛型在这里有什么帮助吗?
  • 这看起来只是实现依赖注入的一种不同方式,而不是它的替代方案......?
  • 不要重新发明轮子。为 DI 使用任何可用的框架。
  • @Rekin 我认为这里不需要泛型。

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


【解决方案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(...),而不必为回调处理任何设置内容。

【讨论】:

  • 对不起,这是一个错字,我将编辑我的原始帖子以更正它。 ExampleManager 有一个 Foo 实例和一个 Example 实例列表。它会修改 Example 对象。 Foo 实例实际上是一个 EventDispatcher,我在 Example 中需要它以便能够在某些条件下调度事件。另一种选择可能是让 Foo 成为单例对象,但我不知道这是否是个好主意。
猜你喜欢
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 2021-01-25
相关资源
最近更新 更多