The story continues …
Mohan was sitting ideally in his room, waiting for his next task to be assigned after promotion. Soon Rahul came to his office,
Rahul: "Congratulation on your promotion Mohan!"
Mohan: "Thanks, Rahul."
Rahul: "As you already know, the US team is moving on to another project. So now it’s our responsibility to sunset their current project, ‘The Dosa Maker’, and come up with an innovative design for the brand new The Dosa Maker V2.0."
Mohan: "In that case, why do we need a V2? can’t we use the same code here?"
Rahul: "Stop talking nonsense, If we don’t duplicate, then who will pay for your salary?"
Mohan: "Got it, I will do my best!"
This is how the Dosa Maker Modules looks like
The Wise Developer: "Do you see any problem with this?"
Mohan: "It’s a mess! Why a single class is handling so many responsibilities?"
The Wise Developer: "Good question Mohan, seems like that promotion wasn’t a fluke!"
A more well-known term for such type of class is God Class. As the class seems to be doing everything instead of delegating those responsibilities to smaller units.
A good guiding principle for finding such a class is to try writing down a brief description of the class without using conjunctions like if, and, also, etc. If you can’t, then probably the class is handling multiple responsibilities. Let’s apply the principle here! The Dosa Maker class takes orders and payment, prepares the dosa, and serves it to the customer.
The Wise Developer: "Do you know why classes with overloaded responsibilities are a bad idea?"
Mohan: "Hmm, I can think of a few reasons."
Testing such classes is hard because:
The wise developer: "Correct!"
But there are a couple of concepts that you need to be aware of, to completely understand why overloading is a bad idea, and those are: Overloading an entity with multiple responsibilities Increases Coupling and Decreases Cohesion.
Mohan: "What does that mean?"
A good system should be ‘high’ on cohesion and ‘low’ on coupling.
Cohesion refers to the degree to which the elements inside a component belong together.
In other words, Cohesion measures the relevance between the logical sub-units within a component. For example, Can you comment on the cohesiveness of this class?
💡Hint: Try finding the logical sub-units first.
The Wise Developer: "What Do you think? I this class ‘highly cohesive’ or ‘slightly cohesive’?"
Mohan: "If we look at the dependency graph of the above class, we can clearly see 3 disconnected entities."
Dependency graph of breakfast maker class
As there is no dependency between these sub-units, I think this class can be categorized as ‘slightly cohesive’.
The Wise Developer: "Yes, that’s a correct observation."
If your class or system is ‘slightly cohesive’, it implies that:
Similarly, a ‘highly cohesive’ system implies that:
For example, A mobile phone can be considered as a highly cohesive system, it has multiple logical sub-units, like a battery, screen, circuit board, camera, etc, and all are dependent on each other, but since all these dependencies are inside our system boundary, it functions very well as an atomic unit.
Coupling is the degree of interdependence between software modules.
In other words, Coupling measures the relevance between multiple modules, i.e, how closely connected two modules are and what is the strength of the relationships between modules. Low Coupling means that there are fewer dependencies on other modules, thereby making systems easier to change, test, and reuse in the future. Conversely, High Coupling means that your module is ‘strongly’ dependent on other modules for its function, thereby making the system:
Food For Thought : Reusability vs Coupling
Mohan: "Is it even possible to have a ‘completely independent system? Don’t you think we will end up re-implementing the functionality of other modules if we focus solely on loose coupling?"
The Wise Developer: "Any system will have some ‘degree’ of dependence on another system, hence it's not possible to create a completely independent system. And you are right, if we focus solely on loose coupling, we will end up violating the DRY principle, which states that we should strive for reducing duplication in our code."
As it happens in life as well, there is no correct answer here, what you need to remember is that ‘a wise developer always strives for balance in conflict i.e. Whenever you have to make a decision between duplicating code and reducing coupling, do the cost-benefit analysis of both approaches, try thinking about what would be more beneficial in the longer term of the project life cycle, and make the decision accordingly.
“A class should have only one reason to change”
— Robert C. Martin
This is popularly known as the Single Responsibility Principle (SRP), a term coined by Robert C. Martin, author of SOLID principles. As an exercise, try breaking down the above Dosa Maker Module using this principle.
Hint: There are 3 separate responsibilities currently managed by the Dosa Maker class, that is:
Enjoy learning, Enjoy oops!
Subscribe to get weekly content on data structure and algorithms, machine learning, system design and oops.