Decomposition, Refactoring, and the Single Responsibility Principle - Day 2/3
Programming is like cleaning a house. It can be long and arduous, you get better at it the more you do it, and when you’re finished it’s usually a great sigh of relief. But sometimes cleaning the house can be a very big job, and when you try to tackle it AS one big job, it can be very overwhelming. That’s why we break it up into smaller pieces. You might say:
First I’ll clean the kitchen.
Then I’ll vacuum the carpet.
Then I’ll do the laundry.
Then finally I’ll do some dusting to spruce the place up a bit, et voila! The house is clean! To take it one step further, each of these steps can be broken down into even smaller ones. In the kitchen, you might need to wash the dishes, wipe down the surfaces, take out the rubbish, etc. But what we can see is we’ve taken “I’M CLEANING THE HOUSE TODAY” and turned it into “I’ve got a few jobs to do around the house”.
In the world of Software Development this process can be called Decomposition, or if you wanna get a little more specific, Object-Oriented Decomposition (but more on that in a later blog). This concept views software as a set of smaller functional parts, or methods, that have their own independent job and purpose. These parts interact with one another to create a part of, if not the whole of, an application or program.
But you might ask, “What’s the point? If I can tackle the problem as a whole, why should I break it all down?”
ENTER: The Single Responsibility Principle
When you’re washing the dishes, you’re not also folding your clean clothes and mowing the lawn, because aside from the fact that that’s ludicrous and you would have to be some kind of superhuman, somewhere, at some point along the line, you’re bound to make a mistake. In Software Development it’s no different. If each method does one thing and that one thing is all it has to worry about, then it’s much more likely to work exactly as we intended it to.
In essence, the Single Responsibility Principle states that each one method or class should have ONE job, and that everything that method or class does should be to perform that job.
“Oh no, I wish I knew this sooner! I made a plan of how I should clean everything up though, so I’m ready to go!
Not so fast! Let me introduce you to my friend: Frederico.
Frederico is your buddy that helps you move house, or tells you when there’s a discount on something you really want. They’re there to make everyone’s lives easier. To go back to our analogy of household duties one last time, let’s say you’ve already finished cleaning the house, but said to yourself
“wow, that still felt like a big task, I wonder if I can do things a little better?”.
Our friend Frederico is here to help! He looks at your plan from before and he tells you about the lady down the road looking to give away her Roomba (what can I say, she’s a generous lady). This means that instead of you manually vacuuming every carpet, the Roomba can do it for you, cutting down the time it takes to clean the house and making your job easier!
In this example, Frederico has given you a great example of something called Abstraction. Abstraction is essentially just hiding the complexity of an object and increasing the efficiency of the code used to build that object. The object that’s left after abstraction is still a representation of what you had originally, but now all the nitty-gritty unwanted details are tucked away from view.
Abstraction is a great example of Refactoring; a very useful way of optimising your code while programming. Essentially what we are doing is changing the overall structure of the code and making it prettier, while still keeping the same functionality. Refactoring helps us eliminate errors, helps other people maintain our code if they need to in the future, and overall can make it more readable and cohesive, making it a very good habit to get into as early as possible.
When we put these three principles together, we’re on the right track towards becoming an effective and efficient Software Developer!