Single responsibility is a concept that has been around for a while.
Wikipedia defines it as:
…a computer programming principle that states that every module or class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.
This helps your codebase be easier to maintain, easier to debug, and easier to learn.
Do one thing, and do it well
Whether you’re building something for yourself, you’re the only one on the team, or you’re part of a giant development team - there’s a certain need for having an “orderly” way of “doing things”.
In my intro post, I started off the introduction to this topic by saying:
script.js is so 2014
Imagine coming into a project for the first time. You’ve been tasked with updating this function on a website:
The above creates an event handler via jQuery (don’t get me started on jQuery), but doesn’t really infer why it exists.
In an Angular 2+ world with TypeScript (when written according to John Papa’s Angular Style Guide), the above code would be written in at least three different files, like so:
There would probably be another file to act as a state class across modules (another Angular Service) to change the CSS as in the first example as well, but I think you get the idea of what I’m going for here.
Writing more code isn’t necessarily a bad thing
I’m of the opinion that it doesn’t go against the idea of pragmatism to be a bit verbose. Writing a bit more meaningful code than would be necessary for the now makes my job of maintaining / adding / scaling the thing I’m doing now easier for me (or someone else!) in the future.
Of course the jQuery code listed first above would work for the purpose we’d want. It did back then! It would do so still. But there’s a way, and then there’s a better way (for all those involved).
My codebase isn’t built with this in mind. Do I have to scratch it all?
Codebases are always changing. We’re always adding to them, deleting from them, and manipulating in between. Start on the path toward single responsibility.
I’ve encountered this in the past. I came into a codebase that had several different frameworks within it. One was used in one part of the app, another in another part. No real rhyme or reason for any of it. I made it my duty to go through and bring everything under the same umbrella.
Developing with empathy means that you keep the following in mind:
- the person before you may not have had the time to think about the bigger picture.
- the person before you may not have had the technical know-how to always think about the most common denominator.
- you should leave the codebase in a better state than it was before you arrived.
- the people you work with now are likely to need your help in keeping the codebase healthy.
- you can’t solve everything.
- the person after you could very well be in the same position you are in right now if you don’t fix what you can.
I made my aspirations for the codebase part of the expected work and not just “outside” the realm of the project work.
This meant bringing items that did similar or even the same thing into one hunk of code by introducing reusable components.
I’ve already employed this strategy. I’m good to go.
Is it? This isn’t a “we built it with this in mind” kind of topic. Quite the contrary - what you wrote on Friday, was it built with this principle in mind? This is an always on principle, and without it always on, you can get lost from it pretty quickly.
At a previous job, my team and I for the most part maintained this principle. This was a codebase I led for a while and I still let some of this slip. It came back to haunt us! When asked about
x being a reusable component, I had to admit that it wasn’t, that it was built specifically for a particular purpose because we didn’t have enough time to generalize it and merge it into our existing patterns. It’s not a failure - but it shows that it requires constant communication with project leaders, designers, and everyone else on the team to maintain a codebase in the most optimal way.
Single responsibility makes its way into CSS too. OOCSS, BEM, and all the other “ways” of doing CSS make some part of this part of their schema too. I’ll expand on this in another post.
Writing a codebase with single responsibility in mind is hard work. It takes a lot of thinking and planning to be comfortable breaking complex ideas up into small bits that all do “their own thing” and can be reused. However, it allows developers and teams alike to work quicker, increase speed and efficiency, and helps onboard new developers and instills good heuristics on what should be “new” and what can be reused.