Raison d'ĂȘtre: I set out to write about the SOLID software development principles. Specifically, my aim was/is to make these things more understandable to other developers who, much in the way as yours truly, found it troublesome to have to decipher lengthy, complex articles and books on the matter. These principles are for everyone to learn and use, but I found that they were hard to fully grasp; quite possibly because I come from a non-English speaking background. So with this series of articles, I'm setting out to try and de-mystify the principles, with only the best intentions in mind. The principles apply to many layers of software development. In my articles, I specifically aim to describe them as they relate to programming. I hope it'll be of use to you. Thank you for stopping by.
This will be a 5 article-series about SOLID. SOLID is all the rage; at least as far as the job-ads I'm reading are concerned; "you are expected to honor the SOLID principles" etc. So what exactly is SOLID about? Plain and simple, it's a set of guidelines in developing object-oriented systems. They are a group of concepts that have proven themselves valuable for a great many people coding a great many pieces of software. A tale told by your elders in software engineering, if you will, that you will want to pay heed to so you can boast on your CV that you're into the SOLID principles - and you'll be a better developer for knowing them, I promise you that. Heck, you're a better developer for simply _wanting_ to know them!
[S]OLID - The Single Responsibility Principle
The Single Responsibility is the first in the set of principles that make out the SOLID acronym. It states that a class should have one single thing to do. And one thing only.
And why is this a good thing? Because the clutter from having a class do too much stuff is long-term damaging to whatever you're trying to design.
As the saying goes here in Denmark, "you're a fool to over-stuff your grocery-bag". Well, maybe that's not so much an official saying, but the analogy will do: If you put too much in your grocery-bag, it's likely to break at the handles, or you got so much in there that you can't get a hold of the chocolate bar you wanted to have when you got back in the car, or you're struggling with the bag and drop the keys to the car in the street... You get the idea. Same with your classes: if you put too much in there, there's a risk involved.
That's what single responsibility is about: leave your classes with just a single thing to do.
Below is listed the primary risks involved in not following the principle, as well as the benefits of, well, following it. But first let's go about how to fulfill the principle. It's very basic:
- Go through your classes and look for those that perform two or more different actions. For example: do you have a class that renders an object AND saves it to disk? Not good - the class is doing more than 'one single thing to do'. For example, with the below example...:
public class Logger
{
public Logger()
{
}
public void WriteLog(string message)
{
}
public void GenerateLoggingStatistics()
{
}
}
... which finds us with a Logging
-class that writes to a log-file and is capable of generating some logging statistics as well.
- Go through the methods of your classes and ask yourself 'why does this method belong here?'. I know it sounds trivial, but I've been caught out too many times myself and have learned the hard way. For example, do you have a logging-component that looks like this:
public class Logger
{
public Logger()
{
}
public void WriteToDiskLog(string message)
{
}
public void WriteToEventLog(string message)
{
}
}
The above has two 'WriteTo
'-methods that can write a log message to the physical disk and to the Windows event-log, respectively. That then too, albeit in a more subtle way, breaks the single responsibility principle - the class should not have to know about how to write to two different kinds of log-storage - that doesn't belong in its main functionality. Do away with the log-storage responsibilities into their own classes, and let them conform to an interface the logging-component can adhere to instead.
So you'll be looking to keeping your classes short. It's not a danger-sign that you have a multitude of small classes as opposed to a few heavy ones - quite the opposite. Keep'em short and lean.
That's it - that's the single responsibility principle, the first of the five. Not so terribly difficult, but then again that's the beauty of the principles, that they're easy to learn but difficult to master. I best saw the adverse of applying the principle described as a 'swiss army-knife class'; if you keep that image in your mind as you traverse your own, you're bound to avoid ending up with exactly those kind of 'do-all' classes. And as an extra positive, classes that are lean and mean are per definition easier to test, easier to read, easier to maintain. And that's what the Single Responsibility principle is all about.