使用依赖注入时如何避免破坏封装

How to avoid breaking encapsulation when using dependency injection

提问人:traveh 提问时间:8/17/2016 最后编辑:Communitytraveh 更新时间:8/17/2016 访问量:151

问:

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

注意:我阅读了如何在不破坏封装的情况下使用依赖注入?但我仍然不是 100% 确定。

我的代码是一个非常简单的线程池实现,其中包含类的对象,这是一个我不想向外界公开的包私有类(这真的不是他们关心的问题)。Worker

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

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

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

多线程单元 测试 依赖关系注入 语言不可知

评论


答:

0赞 jaco0646 8/17/2016 #1

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

s 的创建应在组合根中进行。Worker

评论

0赞 traveh 8/18/2016
我不明白。当类仅与线程池本身相关时,我为什么要向外界公开该类?(这是线程池的实现细节)Worker
0赞 jaco0646 8/18/2016
Worker是一个具体的类。遵循依赖反转原则,任何内容都不应依赖于具体类(组合根除外)。
0赞 jaco0646 8/18/2016
静态方法,包括静态工厂方法,总是违反面向对象的原则。这并不意味着你必须顽固地遵循面向对象的原则。事实上,静态工厂很常见;但是,如果你试图通过依赖注入来松开耦合,静态工厂将做相反的事情。它紧紧地结合在一起。ThreadPoolWorker