Traditional explanations
You’re not a Dummy - here’s why. Take a look at this really simple to understand and quick-to-the-point explanation of SRP:
The single responsibility principle is a computer programming principle that states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.
That’s our British sarcasm showing there - these abstract and wordy explanations really aren’t very helpful to beginners. We know this because we were beginners once, and until these things were explained in context, definitions like this are useless.
That’s because context takes ”abstract understanding” and converts it into ”concrete understanding”
You know you’ve got an abstract understanding about something if you can’t explain it in simple terms, so let’s explain it in real world terms first and then move onto contextual programming examples
Single Responsibility Principle in the Real World
This is Jim (you’ll find out what he’s sad about in a minute)
Jim works as an HR manager for Pear Inc., a company that sells high end laptops.
This is George, his boss (A sassy demon? IDK, the graphic design department is on vacation apparently)
George is frustrated that he needs to go to lots of different employees to get them to do different things, so he gives Jim more responsibilities
Jim’s responsibilities should just be handling things related to an employees contract, such as holiday, induction and exit
On top of this, George wants him to
- Manage the cash flow of the business
- Maintain the website
- Cook meals for everyone at lunch time
- Take pictures of the office dog and post them to instagram
- Post produce the promotional videos for the company
George is violating the Single Responsibility Principle. Not only does Jim do too many things, he does not specialise in any one.
What George should do is hire a videographer, a developer, a chef, a social media manager and an accountant - that would be adhering to Single Responsibility Principle.
Single Responsibility in the Programming World
Obviously, any business owner that forces that amount of responsibility on their single HR guy doesn’t have many brain cells. But in the programming world, single responsibility isn’t completely obvious - and you’d be forgiven for violating it.
Let’s look at two examples to see how to spot it. Here’s the piece of functionality we need to write
- When the user presses the pay button
- We need to get the total price to pay from the items in their basket
- We then need to take their credit card information and pass it to the payment provider
- We then need to redirect the user back to the payment provider’s page
In both examples, everything will happen in a pay
method inside of a ShopController
a class - except one will violate SRP, one won’t. Also, they’re over-commented so you don’t need to worry about the language syntax. Just understand all the different things it’s doing
class ShopController {
// This gets run when the presses “pay now”
public function pay()
{
// Get the basket out of the session
$basket = $_SESSION[‘basket’];
// Get the user out of the session
$user = $_SESSION[‘user’];
// Initialise a variable that will hold the price to pay
$totalToPay = 0;
// Add up the price of all the items in the basket
foreach ($basket[‘items’] as $item) {
$totalToPay += $item[‘price’]
}
// Get the credit card information the user sent through
$creditCardInformation = $_POST[‘credit_card_info’];
// Get the payment gateway key and post the customer, price and card data to stripe
$paymentGatewayKey = ‘A82hDiha9hhdaonldtumpr2390Jf’;
$paymentResponse = API::post(‘stripe’, [
‘credit_card’ => $creditCardInfo,
‘customer’ => $user,
‘price’ => $totalToPay
]);
// If the payment worked, take them to the payment gateway to confirm
if ($paymentResponse[‘success’]) {
return redirect($paymentResponse[‘redirect_url’]);
} else {
// Otherwise, show an error
throw new Exception(“There was an error when attempting to pay. - ” . $paymentResponse[‘error_message’]);
}
}
}
class ShopController {
// This runs when the user presses “pay now”
public function pay()
{
// Create a basket to handle our session basket data
$basket = new Basket($_SESSION[‘basket’]);
// Get the current user
$user = (new Authenticator)->currentUser();
// Create a payment request that holds payment data
$paymentRequest = new PaymentRequest($_POST);
// Pay and redirect the user (this throws an exception if there are any issues)
return $basket->payAndRedirect($user);
}
}
Let’s take score - in the first example, SRP is violated HEAVILY. It is responsible for:
- Getting the user from the session
- Handling post data
- Making requests to the payment gateway
- Summing the total cost of the basket up
- Ensuring the payment was successful and throwing an exception if not
- Redirecting the user to the payment gateway if successful
- Storing the payment key (This is a terrible security risk - your payment key is now in your GitHub repository. Great job, George!)
In the second example, responsibility is offloaded to specialist classes which handle only the things they need to handle. In the second example, the controller is only responsible for:
- Taking the request data and passing it to the necessary specialists
We could dive deeper into the Basket
, Authenticator
and PaymentRequest
classes and these classes might even use their own specialist classes. This is Single ResponsibIlity Principle at its finest!
How do I know when to separate responsibilities, then?
This is hard to learn without just coding and refining over time, and reading experienced developers code. It’s a feel thing - you’ll get a better understanding over time, but here’s a good shortcut.
Read the code of major open source repositories (ones that have a good amount of comments)
Looking at how experienced developers go about separating things in their code is one of the quickest ways to understand SRP. Once again, because it’s not abstract, it’s concrete. It’s in the context of real world code.
Any other programming design patterns you find hard to understand?
Let us know in the discussion below, this is the first post in our “Programming Principles for Dummies” series and we want to make as many of them as accessible to beginners as possible. Because it enables us to write better code!
Curious about frontend development? We’ve just released a free crash course (No, it’s really free - no upgrades, no hidden costs)
We worked for a couple of months on a professional design and 4 hours 20 minutes of video content to bring you our free crash course showing you how to code this portfolio website (which we constantly encourage you to customise to your own style)
If that’s something that would interest you, and you’d like to learn more about HTML, CSS, SCSS, Bootstrap 4, Git, GitHub Pages and a sprinkle of JavaScript and jQuery, you can register today, for free, from this link here.
Top comments (8)
Probably the easiest explanation.
will try to follow SRP
thanks for this
Glad you think so Bhupesh! SRP is so important!
The reason why I follow you. I love this <3
More to come! We've got a mega post on design principles coming up soon :)
Thank you for good explanation. I'll waiting for next article.
Deep dive on YAGNI up next
Love your content Skill Pathway! For sure one of the best making developer content out there!
Thanks so much for the kind words João - we really appreciate your feedback! Please let us know if there’s anything else you want to see from us