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.
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.
Yes. Worried about not "using" httpService inside webGetTaskFactory. So I inject a "httpService" object into a "webGetTaskFactory", "webGetTaskFactory" only ever uses "httpService" when it creates a new "webGetTask".
And this is OK. Cool. Is there a more "text-book" example for doing this?
Or is this the most common way to create objects that require a specific dependency on its constructor? – Titi Wangsa bin Damhore Apr 27 '09 at 12:31 If you think about it, the factory performs "run-time dependency injection". This is the natural way if you want to follow the dependency injection patterns for objects that are created dynamically at run-time, as opposed to design-time.
– Wim Coenen Apr 27 '09 at 14:41.
Okay, there's nothing specifically wrong under the LoD about passing an implementation object, a "plugin" in the constructor. What's important is that the interface of the class doesn't tell you much about that implementation. If your interface to WebGetTask depends on the exact implementation of HttpService, that violates the Law of Demeter.
The trick here is to think about the interface signature of WebGetTask. The name itself suggests that you're not quite following the Law of Demeter — or principle of least knowledge — because you're defining a class that (1) is defined as being specific for the web, and (2) is a verb instead of a noun. Now, neither of those is necessarily wrong, but they are both "OO smells" if you will, signs that you may not be thinking object-ly enough.So let's try "refactoring" the design.
First thing, think about a GetTask that has no "web" associated with it. You can then, either at construction time or at some later time build a service object and pass it in. If it's HttpService, that's fine, but the user of your class doesn't need any information about what's under the covers.
Second thing, let's make it a noun. Call it TaskFactory — your intuition was leading you right there — with a ctor that takes an IOService, which I've just invented as being the abstract interface implemented by HttpService. Now, you have (this is sort of Java/C++ pseudocode, don't get excited about syntax details): class Task { ... } class TaskFactory { public TaskFactory(IOServer svc){...} public Task get(){...} } and you use it by writing TaskFactory fac = new TaskFactory(new HttpService()); Task tsk = fac.get(); Now, we kow the minimum about the innards of TaskFactory, the IO service, and for that matter Tasks.
There are two ways of DI: the first one is a constructor one, which is usefull when only one or two objects are injected, and a setter one (actually as many setters as needed). If you want to use a factory method for DI than in principle its same as a constructor based one. Example 1, for a constructor DI: list.
Add( new WebGetTask( httpService ) ) ; Example 2, for a setter DI: WebGetTask webGetTask = new WebGetTask(); webGetTask. SetHttpService(httpService); // set other dependencies list. Add(webGetTask); The factory method is best for when you need to use some greater logic when creating objects that may behave differently, but have the same interface, thus the LoD.
Lets assume there is a DownloadManager interface implemented dynamically based on the factory parameter(s). Example 3, creation logic encapsulated into a factory method: public static DownloadManager createDownloadManager(HttpService httpService){ if(null! =httpService){ WebGetTask webGetTask = new WebGetTask(); webGetTask.
SetHttpService(httpService); // set other dependencies return new DownloadManagerImpl1(webGetTask); } else { return new DownloadManagerImpl2(); } // if-else }.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.