I'm going through the code of the biggest program I've ever created from scratch and seeing if there are things that I can improve in the design. When I first created the program, I was using Singleton everywhere, but since then I've removed them completely and instead switched over to using Dependency Injection. One thing I noticed is that some of the classes have kind of beefy constructors since I inject all the needed classes. For example, I have one class that reads messages from a serial port and then saves them to a message queue. Then I have a class called MessageHandler that collects messages from the queue and then delegates them to the correct part of the system. This MessageHandler class currently has six classes injected in the constructor. Is this ok for a class that basically just forwards the messages to the correct receiver or is it a sign that I need to rethink my design?
3 Answers
You want to keep the amount of dependencies low. A class with many dependencies probably violates separation of concerns.
But there is no hard and fast rule about how many dependencies are too many. Six dependencies does not immediately sound like a problem to me, it very much depends on the individual case.
It is not in itself a problem if a class does nothing else than delegate. This is for example what the adapter pattern does.
Is it ok to have a many dependencies in a class that just delegates work?
Yes (as long as they really belong there)
I don't think having a class with a lot of fields is a bad thing. Its an intermediate stage as part of regular refactoring. The next step is usually identifying classes that are generally together at different places and wrapping them into their own object/class.
My personal rule of thumb is 3 classes but I'm not too dogmatic about it. As long as stateful objects are being injected (with sane configuration) instead of created from thin ether (Singleton/Static Factories), its alright.
-
4
-
In the software world, there's a design pattern to address exactly this problem (just like any other common software problem). It's called the Adaptor pattern. And unless your initialization and access code uses some sort of sorcery(read: Reflection), yes, it will have a lot of module dependencies.
Well, at least the modules which houses your service factories. The idea of all that being, in future, it might be required to replace a module with just another one. Since the interface to the module shouldn't change (for backward compatibility), one can surmise that Adaptors won't change, except for the new set of dependencies, required to initialize the new services.
The adaptor is supposed to be a one stop solution for inter module communication, meanwhile also promising future proof design. The reason which enables the adaptor to be a know-it-all is that they themselves can access a lot of other services (directly or via some sorcery) to get the client done what it wants.
Note the distinction between adaptors and facades, although they might look structurally similar, but they were born to serve disparate purposes. Facade has less to do with dependency and more to do with clean design to avoid obfuscation to clients.