Reputation: 18690
When my constructors are pure arguments-to-propeties setters then I'm not sure where to put other code that a class needs to properly work.
For example in JavaScript I'm programming a WindowMessageController
that processes message
events on the window
object.
In order for this to work, I must somewhere attach the handler:
var controller = this;
this.applicableWindow.addEventListener("message", function(event) {
controller.messageAction(event.data);
}
Where does this stuff correctly belongs?
EDIT
This case seems special because there is usually only one instance of such a controller in an app. However in more generalized case what would be the answer if I was creating an instances of Button
class that would wrap over some DOM <button />
element? Suddeny a
button = buttonFactory.create(domButtonEl);
seems much more useful.
Upvotes: 0
Views: 349
Reputation: 1101
Do not put any real work into constructors. Constructors are hardly mockable. Remember, seams aka methods are mockable. Constructor are not mockable because inheritance and mocking.
Initialize is a forbidden word, to much general.
Maybe, but you can implement factory as a static method of class too, if you are scared of many classes ,)
Composition root is just an ordinary factory. Except it is only one, because your app probably have just one entry point ,)
Common, we are using Javascript. If you need just one factory method, why you need class for it? Remember, functions are first class objects.
And for edit. There is nothing special on singetons, unless they do NOT control own lifecycle.
Golden rule: Always (almost ,) do separation between app wiring and app logic. Factories are wiring. Just wiring, no logic, therefore nothing to test.
Upvotes: 2
Reputation: 1462
I think you need to create a Router class that will be responsible for events distribution. This Router should subscribe to all the events and distribute them among the controllers. It can use some kind of the message-controller map, injected into constructor.
Upvotes: 0
Reputation: 361
I would place this code into initialize(window) method but this method cannot be part of WindowMessageController's public API - it must be visible and called by direct users (so composition root and tests) only. So when DI container is returning WindowMessageController instance then it is container's responsibility that initialize method has been called.
Reply to EDIT: Yes, this factory seems to be the best way for me. Btw. don't forget that the factory should probably have a dispose method (i.e. unbinds the event handler in case of button)...
Upvotes: 1