Search code examples
dependency-injectionlaw-of-demeter

Law Of Demeter on Factory Pattern and Dependency Injection


I have a question regarding dependency injection.

say i want to create a class call it, WebGetTask

WebGetTask would need a dependency to HttpService

bad code 1 Code:

private HttpService  httpService;
...   
List<WebGetTask> list = new ArrayList<WebGetTask>();   
for(...)   
{   
   list.add(new WebGetTask(httpService)); 
}
...

ok. i know this is bad, because httpService is injected, but its never used, except for the creation on a new WebGetTask

ok bad code 2 Code:

private WebGetTaskFactory webGetTaskFactory;
...  
List<WebGetTask> list = new ArrayList<WebGetTask>();  
for(...)  
{   
    list.add(webGetTaskFactory.newTask());  
}  
...

i think this is better, because we use a factory but... but..

from where i'm standing, i can see that in WebGetTaskFactory we are still injecting a HttpService and not doing anything to it except for the sole purpose of creating a new WebGetTask

so to recap my question is how do i design a factory class (WebGetTaskFactory), that creates new objects (WebGetTask) when the new objects require a dependency (HttpService) on their constructor without simply injecting and passing the dependency (HttpService) ? or rather, is this the way to do it? if so, then it's all good, if its not, then please guide me to how to properly use DI and factory pattern. thanks.


Solution

  • I'm going to assume that the code you have shown is part of a DownloadManager class, and that you inject your dependencies via the constructor. In this case, I would expect the start-up code which glues everything together to look like this:

    IHttpService httpService = new HttpService();
    IWebGetTaskFactory webGetTaskFactory = new WebGetTaskFactory(httpService);
    IDownloadManager downloadManager = new DownloadManager(webGetTaskFactory);
    

    The DownloadManager class only knows about the IWebGetTaskFactory interface. It does not know about IHttpService, thus satisfying the law of Demeter.

    edit: After re-reading your question, it seems that you are worried that you are not "using" the HttpService in your factory, except to pass it on to a new WebGetTask. This is OK. Both WebGetTaskFactory and WebGetTask need an HttpService instance to do their job. This is not a violation of the law of Demeter.