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