Right Syrup
Today we are going to look at the most important stimulus to sustaining a software project on the Right Path. Of course we are talking about Single Responsibility Principle.
In Right Start I introduced the concept of Right Path - the vector that sustains a successful software project. I say vector because the Right Path ends at the Right System (future post). There are many forces pushing, punching, and kicking a system off the Right Path onto the Compromise Path - some of them are out of the software engineer's hands. But usually the reason a software project ends up on the Compromise Path, let's face it, is the development team made compromises. Yup, it's usually on us.
No offense guys, really. But if we're going to be honest, let's be honest. When the rails come off, it is usually traced back to compromises in discipline. I could spend quite a while now writing about discipline...and it would be really good stuff, but my own discipline right now points to delaying that for a future post. What we need to look at right now is literally the Magic Wand for everything. Yup. Everything.
Syrup
Single Responsibility Principle, or SRP (or Syrup as I like to call it due to it being the Secret Sauce and all), is a lot of things but what I want you to know about it is real simple: it is the best damn discipline practice that exists in software engineering. If you commit your every symbol, your every line of code, your every definition, your every taxonomy - if you just do SRP, then you and your software project are on the Right Path to the Right System.
What is SRP? I don't really care. I don't think you should either. It's the discipline that matters. If you want a definition here ya go, but again I think the discipline is the real value in SRP, not the definition. What is SRP discipline? Wherever SRP is applied, the target does just one thing (one responsibility). That's it. Even SRP uses SRP!
Now maybe you have "done" SRP. Maybe. No offense, but more likely you have done what the definition says, and not taken SRP as a discipline. This is where even the guy that coined SRP does not go far enough. When you apply SRP to every aspect of software engineering, that is when you get the big payout. That is when you are in Closed Loop Discipline. Let's look at some examples of this crazy talk and maybe you won't think I'm crazy at all.
Taxonomy
What could naming have to do with responsibility? Plenty. The most important connection is that if you use SRP when naming a thing, you are already thinking of that thing in terms of a single responsibility. You see how the discipline is flowing already?!
Let's say we are writing a payroll system. You might imagine in this system we have employees, bank accounts, payments, etc. Let's say we get to the point of writing the thing that figures out how much to pay an employee. What do you call that thing? Well, sometimes we look to real life for inspiration for our names...and in real life that could be a payroll manager. Let's call it PayrollManager, eh? Let's look at what PayrollManager looks like after a few iterations.
public class PayrollManager {
public IMoney CalculatePay(IEmployee employee) {}
public IMoney CalculateTax(IEmployee employee) {}
public void PayEmployee(IEmployee employee, IBankAccount account, IMoney pay, IMoney tax) {}
public void RollAccount(IBankAccount account) {}
}
Not too bad. Not too bad, until the system changes - and change it may. For example, back a few years I switched payroll vendors...so I know that can happen. What about if the rules around rolling an account changes? Or if (gasp!) tax law changes?
By naming PayrollManager as such we are directly encouraging Multiple Responsibilities. When a single thing has Multiple Responsibilities it becomes more and more difficult to avoid side effects. You know what I'm talking about. I'm sure you've been there. You go into a class to make an improvement and leave behind an unintended bug. Why? Because you are not omniscient. You are damn good...but you cannot know everything about all things. If you don't know about PayrollManager's other responsibilities, you may inadvertently break something. And how can you know its other responsibilities just by its name? You can't!
Let's take another whack at naming here...but using SRP discipline. I know that pay is basically gross pay minus deductions, so let's start with CalculateGrossPaymentCommand.
public class CalculateGrossPaymentCommand
{
public IMoney Execute(IEmployee employee) {}
}
I really can't put much of anything else in that class. It's name is almost forcing me to only deal with one single responsibility: calculating gross pay.
Take a moment. Think of your system. Think of all the systems you have worked on. Think of your next system. If you used SRP for your taxonomy, everywhere, think of the impact. When I think of that I feel relief. Why? Well, 'cuz I ain't smart enough to know everything about all things. When you don't have to do that, when a thing in your system clearly names it's sole responsibility, then you can focus on the one small task you should be doing right now (future post) and not worry about what you don't know.
When you have used SRP in taxonomy for a while, you see you can and must apply it to everything from packages, namespaces, types, members, fixtures, TESTS (absolutely a future post).
Conclusion
I like how this post unfolded. I wanted to share the real value in SRP - and inevitably it led us back to the concept of Right Path. No shock there. If what you are doing is not keeping your software project on the Right Path then stop doing it! Do something that does.