【问题标题】:How to avoid breaking encapsulation when using dependency injection使用依赖注入时如何避免破坏封装
【发布时间】:2016-12-24 00:18:14
【问题描述】:

在阅读和观看了一些有关依赖注入的视频后,我仍然不明白如何在不破坏封装的情况下正确使用它。

注意:我阅读了How to use Dependency Injection without breaking encapsulation?,但我仍然不能 100% 确定。

我的代码是一个非常简单的线程池实现,其中包含 Worker 类的对象,这是一个我不想暴露给外界的包私有类(这真的与他们无关) .

我的线程池构造函数需要一个参数Worker[] workers(我不需要工厂,因为我提前知道我需要多少工人)。

由于我的Worker 类是包私有的,我认为构建线程工厂的正确方法是在ThreadPool 类中实现静态工厂方法,如下所示:

public static ThreadPool createThreadPool(int numOfWorkers, 
                                          BlockingQueue<Runnable> jobQueue, 
                                          ThreadFactory threadFactory) {

    Worker workers[] = new Worker[numOfWorkers];
    for (int i = 0; i < workers.length; i++) {
        workers[i] = new Worker(jobQueue, threadFactory, i);
        // worker needs the factory in order to provide itself as Runnable
    }
    return new ThreadPool(workers, jobQueue);
}

那么,在静态工厂方法中创建所有这些新对象是从其他包中隐藏 Worker 类的正确方法,还是我在这里遗漏了什么?

【问题讨论】:

    标签: multithreading unit-testing dependency-injection language-agnostic


    【解决方案1】:

    依赖注入意味着对ThreadPool 隐藏Workers 的创建。理想情况下,Runnables 应该被传递到ThreadPool 构造函数中,ThreadPool 甚至不应该知道Runnables 恰好是Workers。

    Workers 的创建应该在 composition root 中进行。

    【讨论】:

    • 我不明白。当 Worker 类只与线程池本身相关时,我为什么要向外界公开它? (是线程池的一个实现细节)
    • Worker 是一个具体的类。在Dependency Inversion Principle 之后,什么都不应该依赖于具体的类(组合根除外)。
    • 静态方法,包括静态工厂方法,始终遵循violate面向对象的原则。这并不意味着您必须顽固地遵循面向对象的原则。确实,静态工厂很常见。但是如果你试图通过依赖注入来放松耦合,静态工厂会做相反的事情。它将ThreadPoolWorker 紧密耦合在一起。
    猜你喜欢
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 2023-02-17
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多