SRP, as easy as 123…

…of course, you’d need to have the song ABC from the Jackson Five in your head for that title to be remotely amusing.

Single Responsibility Principle is such a simple principle. It states that a class should only have one responsibility. One responsibility. Not two, not three, one. Such a concise and simple definition is hard to get wrong, right? Right? RIGHT??? Hmm…

clip_image001

A conversation between two friends

I’m looking at this Customer class, it does a bit too much no?

Huh? What do you mean? It’s a Customer Class. It deals with Customers. That’s all it does. Not Employees. Customers. I can fetch a customer. I can fetch a lot of customers. I can store a customer. I can calculate their age. I can check if they are VIP customers. Everything there is to do with customers. That’s all it does. Isn’t that what this Single Responsibility Principle states? To only have one responsibility?

Well, yes, but I think you’ve kind of missed the point on what this whole responsibility thing is .

How so? It just deals with Customers right? In fact, isn’t what I’ve just described pretty much the ActiveRecord Pattern?

Indeed it is.

So then WTF is the problem? I don’t get it.

Digging deeper…

Hmm, let’s look at this class. It reads/writes a customer(s) from/to the database. Therefore it has some code that has to do with reading from a database. It calculates age and verifies if a customer is a VIP. So it must have some business logic code in there.

What happens when you need to change the persistence logic?

Well I’ll change the code.

Which code?

The Customer class of course.

Right. What happens when you need to change the business logic of how a customer is considered a VIP?

I’ll change it again…..Sorry. What’s your point?

So again, you’ll touch that class. What happens when Customers need some validation? You’ll again have to touch the same class.

And?

What happens when you touch code? You usually end up breaking things. And it’s not necessarily that particular thing you touch. You break other things that at that point you had no clue were somehow related. The more complicated the code, the more chances you have of breaking something. Of course, if on top of everything,  you don’t even have regression tests…well I’m sure you’ve suffered the consequences.

I kind of think of myself a competent developer. I’m sure I can work with enough care to not break things.

Right…. Now while you go and convince yourself of that, let me explain another problem. You see, writing code is easy. Understanding it is hard. The more code in a class, the harder it will be to decipher. The less code, the easier it will be to comprehend. If a class does many things, it will most likely have what? More code. The less it does, you got it! Less code. Forget logic for a moment. It even has psychological impacts. Open a large class and a small one. Which one will depress you more?

I have no problem understanding my own code. 

Sure. You’re very smart and you’ve worked on this code base and you know it well. What about other team members? Hell. Forget others. Why don’t you look at code you wrote yourself eight months ago. Do you know what it does?

Well mostly yes. But I guess that’s kind of why comments are useful

Why do you need comments if your code is clear enough to understand? And you know why your code is hard to understand? Because you’re trying to solve too many problems at the same time. Think about it. You’re doing Customer listings, storing, reading and some business logic. It might be the case that for this particular example it’s not too hard to understand, but that’s because both of us have beaten Customer management to death (along with Authentication) so we’re experts in it. But imagine being thrown into some code that you have little knowledge of the domain. Is it easier to understand a class if it does one thing or five? 

So what are you proposing?

It’s actually very simple. Divide and Conquer. Remember that? Back from our College days? Divide up a problem into smaller problems and solve the smaller issues. Dealing with mini-problems is easier than dealing with mega ones.

When we take a class and divide it up into smaller classes, it will be easier to deal with it. And dealing can mean both understanding it and modifying it. But if your customer class is doing all that, it’s bound to be harder to understand and maintain. That’s why it’s important to get these responsibilities right.

I see. But where have I gone wrong then? I kind of thought I understood the Single Responsibility Principle. Going back to my Customer class, how do I define what the responsibility is if it’s not “dealing with customers”?

Getting a grip on responsibilities

The main problem in complying with SRP is defining the responsibilities. Where do we draw the line? A few things that have helped me along the way have been…

Change

Have you ever heard people say:

“A class should only have one reason to change”

when talking about Single Responsibility?

Yes, actually I have. 

Well think about it. If a class changes for more than one reason, it must be because it’s doing more than one thing. Going back to your customer class, think how many reasons there is for it to change. If we have to touch the same class for changing different things, the risk of breaking something is higher, which leads to higher costs in maintainability.

One way therefore of trying to figure out the responsibilities of a class is by asking the question of how many reasons are there for it to change.

Naming

Naming is a good way to discover the responsibilities of a class. What does your class do? Give it a name describing what it does. Does it use And or Or? Is it hard to explain what it does? Do you need to use suffixes like Manager, Processor or Admin because you can’t pinpoint the exact word describing what it does? Maybe it’s because it does two things that one word can’t describe. These are all clues that your class is doing more than one thing.

Cohesion

Take your class. Look at your methods. Do they have parameters or are they using instance fields? If they are using parameters, remove them. Make them instance fields. Do you end up with methods that only use one of the five instances? That most likely is a warning of the low cohesion that exists between that method and your class. Cohesion is a indication of how well related lines of code are, how well related methods are to a class. 

And you use ReSharper right. Next time ReSharper prompts you if you want to make a method static, it’s telling you it does not use instance fields. That’s where you need to decide if that method actually belongs in that class. Sometimes it might, many times it might not.

 

OK, that’s kind of making sense.

Wait though. Many look at Single Responsibility Principle as something that applies only to classes. Wrong. It applies to methods too. The more things your method does, the more lines of code. The more lines of code. The harder to understand. The harder to debug.

Use the same process to identify responsibilities in methods. How many reasons do I have to change the method? What do I name it? If I can’t name it on a single line, bad! If I can’t name it without using And/Or , bad!

Refactor your methods to smaller ones. Give each smaller method a good name. Make it descriptive. Don’t waste time trying to comment your methods and the 20 parameters it takes. If it’s well named and has one or two parameters at most, it should be self-describing. Remember, parameters are used to operate on values, not decide what path to take in the method. For that, you create two methods.

(Beer enters the scene…)

Hahahhaha…

What?

I remember back when I first started using non-locking source control, I was concerned about running into conflicts when merging. I was right. I did run into issues. I bitched at the SCM. But now that I think of it, the problem wasn’t the SCM. It was the way I was working. It was having too much code in the same class.

Yep, and that would lead to contention since many people would need to touch the same code.

Yep. I was fighting the wrong problem. Damn, it seems such a simple principle, but hard to get right then….

Yes. It’s about asking the right questions. Single Responsibility Principle is about making code maintainable and understandable. That’s all there is to it really.

Right. Well dude, I guess it’s time for me to Refactor out that Class.

Yep. Oh and do yourself a favor. If you’ve not read the book Clean Code by Robert C. Martin (@unclebobmartin), get it. It teaches you much of what we’ve been talking about.

Cool!


Posted 12-18-2010 4:55 PM by Hadi Hariri
Filed under: ,

[Advertisement]

Comments

Julian Birch wrote re: SRP, as easy as 123…
on 12-18-2010 12:15 PM

Problem is, understanding SRP requires you to solve one of the two hard things in computer science...

PK wrote re: SRP, as easy as 123…
on 12-18-2010 8:57 PM

A very good post.

But, I have seen SRP being abused in one of my projects, where the developer ended up with 100+ classes for a very small module.

Eric Schaefer wrote re: SRP, as easy as 123…
on 12-19-2010 3:24 AM

@PK: Every principle can be abused. That doesn't make the principle wrong.

Simon wrote re: SRP, as easy as 123…
on 12-20-2010 10:07 AM

Having seens somebody without a tool like Resharper installed attempt to follow code written with SRP is quite revealing. It's not a pretty sight.

One area I struggle with, is how to apply SRP to User interfaces. Currently, I am in a ViewModel/Controller bloat phase, and finding it difficult to break out of this coordinator/god class anti-pattern.

halcharger wrote re: SRP, as easy as 123…
on 12-20-2010 10:47 AM

I have a question about SRP relating to a scenario. the scenario being a class that does the following:

picks up a msg (xml) of a queue

deserializes the msg

maps the msg from the DTO format it was picked up off the queue in into an "entity"

saved the entity to a database

The above scenario clearly does five different things, it's very procedural and each step only requires one line of code. The class containing this logic is call MessageProcessor (surprise surprise).

Does this break SRP (I'm presuming so) and how would you refactor it to adhear to SRP.

My concern is that each step is only one line of code (hence very understandable) breaking it out into five seperate classes (each representing one of the five steps) would result in more code not less.

your view would be appreciated. cheers.

Tudor wrote re: SRP, as easy as 123…
on 12-20-2010 12:25 PM

Indeed, it's easy to describe SRP, but it's much harder to propose actual and concrete solutions.

Your post would be much useful if you describe a concrete refactoring for the class described initially.

One extreme solution would be to have each method in a single class, but this is not a real solution in complex projects.

So following SRP it's harder than it might seem - you have to reconcile different goals: having classes that encapsulate state and behaviour; ideally a class should be easy to understand and splitting it mechanically into 5 classes, even if we call them "decorators" or "behaviors" it's not always the solution - the application just increases in complexity and becomes harder to understand.

Another hard question is: how do you define "responsability" for a class? How do you establish the granularity? How do you split a class in several smaller ones without breaking encapsulation and exposing internal state to the outside world? How do you avoid going back to 'procedural' programming with classes that have only behaviour but no state/data?

Joshua Sigar wrote re: SRP, as easy as 123…
on 12-20-2010 1:20 PM

<blockquote>"But, I have seen SRP being abused in one of my projects, where the developer ended up with 100+ classes for a very small module."</blockquote>

Abuse or everyone has different interpretation of SRP? Basically it's the problem Tudor mentioned ^^

Hadi Hariri wrote re: SRP, as easy as 123…
on 01-01-2011 4:49 AM

@halcharger

What would be the problem of having simple classes with one-two methods? All it does is add clarity and decoupling.

Hadi Hariri wrote re: SRP, as easy as 123…
on 01-01-2011 4:51 AM

@Tudor,

The approaches I describe have worked for me and I think they qualify as ways to approach the problem.

Wayne M wrote re: SRP, as easy as 123…
on 01-03-2011 9:13 AM

Good article.  IMO the Active Record pattern itself is a gross violation of SRP, although in many cases that violation is acceptable because of the benefits it provides.

2010 movie base wrote re: SRP, as easy as 123…
on 01-11-2011 7:48 PM

<a href="filmspack.com/">2010 movie base</a>

bookmarking submission wrote re: SRP, as easy as 123…
on 10-20-2012 7:02 PM

PYu6iW Fantastic article post. Really Great.

buy generic stendra wrote re: SRP, as easy as 123…
on 01-27-2013 6:07 AM

V3mPZl Very good post.Thanks Again. Will read on...

lose weight pills wrote re: SRP, as easy as 123…
on 02-01-2013 10:30 PM

mqp3Jt I value the blog article.Really thank you! Will read on...

buy viagra online wrote re: SRP, as easy as 123…
on 02-03-2013 5:46 PM

nM2HmN wow, awesome blog post.Really thank you! Cool.

buy discount viagra wrote re: SRP, as easy as 123…
on 03-02-2013 2:26 PM

mKnm7i Enjoyed every bit of your blog article.Really thank you! Really Cool.

bookmaring service wrote re: SRP, as easy as 123…
on 03-14-2013 10:39 AM

xGmU5g Awesome post.Thanks Again. Really Great.

Social bookmarks wrote re: SRP, as easy as 123…
on 03-23-2013 3:40 AM

FryQAg Really appreciate you sharing this article.Thanks Again. Awesome.

buy social bookmarks wrote re: SRP, as easy as 123…
on 04-03-2013 10:49 AM

UvcevO I am so grateful for your article.Thanks Again. Awesome.

nonsense wrote re: SRP, as easy as 123…
on 04-05-2013 4:41 PM

Very good blog post.Really thank you! Will read on...

Social bookmarks wrote re: SRP, as easy as 123…
on 04-07-2013 7:23 PM

gjktZS Great, thanks for sharing this article post.Thanks Again. Will read on...

Social bookmarks wrote re: SRP, as easy as 123…
on 04-19-2013 10:52 AM

LykxXf Thanks for the article post.Really looking forward to read more.

super news that are fun wrote re: SRP, as easy as 123…
on 08-04-2013 8:11 PM

irD0gS Thanks for sharing, this is a fantastic article.Really thank you! Want more.

awesome links for you wrote re: SRP, as easy as 123…
on 08-20-2013 12:53 AM

Tkytmo Great post.Much thanks again. Really Cool.

great link buildng wrote re: SRP, as easy as 123…
on 08-21-2013 7:35 PM

mEWMCE Fantastic article post.Much thanks again. Really Great.

the best seo service wrote re: SRP, as easy as 123…
on 09-06-2013 9:13 AM

u0um34 I appreciate you sharing this blog.Really looking forward to read more. Awesome.

make money online wrote re: SRP, as easy as 123…
on 09-12-2013 9:08 PM

Jchowb Thanks for sharing, this is a fantastic article. Want more.

cheap link building wrote re: SRP, as easy as 123…
on 09-24-2013 6:14 AM

o8tsvi I really liked your blog article.Much thanks again. Much obliged.

check out seo wrote re: SRP, as easy as 123…
on 09-29-2013 10:39 AM

ic4Led Really informative blog.Much thanks again. Cool.

best link build wrote re: SRP, as easy as 123…
on 10-16-2013 6:26 AM

TBJowg Hey, thanks for the article.Thanks Again. Really Cool.

link building wrote re: SRP, as easy as 123…
on 10-25-2013 7:13 AM

tF1dtb Very informative post.Really looking forward to read more. Much obliged.

awesome site wrote re: SRP, as easy as 123…
on 11-20-2013 10:22 AM

J8kRbA I think this is a real great post. Great.

check it out wrote re: SRP, as easy as 123…
on 01-22-2014 11:23 AM

H4vh8T I really like and appreciate your blog article.Thanks Again. Awesome.

nice seo guys wrote re: SRP, as easy as 123…
on 03-22-2014 9:30 AM

Hzf97X Great blog article.Really thank you! Will read on...

nice seo guys wrote re: SRP, as easy as 123…
on 03-25-2014 12:42 PM

IStlsd I value the article post.Much thanks again. Much obliged.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)