0

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

注:我读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类的正确方法,还是我在这里丢失了一些东西?

回答

0

依赖注入将意味着从ThreadPool隐藏创建Worker。理想情况下,应将Runnable s传递给ThreadPool构造函数,并且ThreadPool甚至不应该知道Runnable恰巧是Worker s。

创建Worker s应该发生在composition root

+0

我不明白。当它只与线程池本身相关时,我为什么要将'Worker'类暴露给外部世界? (这是线程池的实现细节) – traveh

+0

“工作者”是一个具体的类。遵循[依赖倒置原则](https://en.wikipedia.org/wiki/Dependency_inversion_principle),什么都不应该取决于具体的类(组成根除外)。 – jaco0646

+0

静态方法,包括静态工厂方法,将始终[违反]面向对象的原则[http://stackoverflow.com/questions/4002201/why-arent-static-methods-considered-good-oo-practice]。这并不意味着你必须顽强地遵循面向对象的原则。事实上,静态工厂很常见,但是如果你试图通过依赖注入来放松耦合,那么静态工厂会做相反的事情。它将'ThreadPool'和'Worker'紧密结合在一起。 – jaco0646