Low Level Design 105 | Single Responsibility Principle in SOLID | 2022 | System Design
Summary
TLDRThis video delves into the Single Responsibility Principle (SRP), a key concept in SOLID design principles. Contrary to common misconceptions, SRP doesn't imply a class should have only one method or reason to change. Instead, it emphasizes that a class should have one reason to change, driven by a single 'actor' or stakeholder. The video uses Uncle Bob's 'Clean Code' to illustrate this with examples like an 'Employee' class and a 'Bill' class, showing how changes in one part of a class can affect other functionalities if not properly separated. The solution? Decomposing classes to ensure each handles a single responsibility, thus adhering to SRP and making software easier to maintain and less prone to unintended side effects from changes.
Takeaways
- đ The Single Responsibility Principle (SRP) suggests that a module or class should have one reason to change, meaning it should address the needs of one actor or stakeholder.
- đ« Contrary to common misconceptions, SRP does not imply that a class should have only one public method; rather, it emphasizes that changes to the class should be driven by a single business requirement.
- đšâđ« Uncle Bob's book 'Clean Code' provides a detailed explanation of SRP, using examples to illustrate how a class can serve multiple methods corresponding to different stakeholders without violating the principle.
- đ The term 'actor' in SRP refers to different stakeholders or departments within a system that might require changes to the functionality provided by a class or module.
- đĄ SRP is about ensuring that the impact of changes is isolated to the part of the system that is directly related to the stakeholder requesting the change, thereby minimizing unintended side effects.
- đ ïž When a class is changed to meet the needs of one stakeholder but inadvertently affects the functionality used by another, it indicates a violation of SRP.
- đ To adhere to SRP, it may be necessary to refactor a class into multiple classes, each with a distinct responsibility, allowing for independent changes without cross-functional impacts.
- đ The example of an 'Employee' class with methods for calculating salary, hours, and saving data illustrates how a single class can serve multiple actors, but changes in one area can ripple through to others if not properly designed.
- đą The script uses a restaurant app scenario to further explain how SRP can be applied in practice, suggesting that classes like 'Bill', 'BillPrinter', and 'BillStore' should be separate to handle different responsibilities like calculating, printing, and storing bills.
- đ€ SRP is subjective and requires judgment; it's about balancing the number of classes with the need to make the software easy to change and maintain without breaking existing functionality.
Q & A
What is the Single Responsibility Principle (SRP)?
-The Single Responsibility Principle (SRP) is a software design principle that states a class or module should have only one reason to change, meaning it should only have one responsibility. It implies that the class should be designed in such a way that it encapsulates the functionality that caters to the needs of one particular stakeholder or group of stakeholders.
What does the term 'actor' mean in the context of SRP?
-In the context of the Single Responsibility Principle, 'actor' refers to a stakeholder or a group of stakeholders who have a specific interest or requirement that could lead to changes in the software. It could be a department within a company, like the CFO, HR, or IT, each of which might require changes to the software for different reasons.
Why is it important to adhere to the Single Responsibility Principle?
-Adhering to the Single Responsibility Principle is important because it helps in creating a modular and maintainable codebase. When a class has only one reason to change, it reduces the risk of unintended side effects when modifications are made. This principle contributes to a design where changes in one part of the system are less likely to affect other parts, thereby enhancing the overall stability and reliability of the software.
Can you provide an example from the script that illustrates the violation of SRP?
-An example from the script that illustrates the violation of SRP is the 'Employee' class with methods like 'calculate salary', 'calculate hours', and 'save employee data'. These methods cater to different stakeholders (CFO, HR, and IT), and changes in one method due to the requirements of one stakeholder can inadvertently affect the functionality used by another stakeholder.
How can the violation of SRP be resolved according to the script?
-The script suggests resolving the violation of SRP by decomposing the class into multiple classes, each with a single responsibility. For instance, creating separate classes like 'SalaryCalculator', 'HoursCalculator', and 'Store' for handling salary calculation, hours calculation, and data storage respectively, ensures that changes in one class do not impact the others.
What is theFacade Pattern mentioned in the script, and how does it relate to SRP?
-TheFacade Pattern is a design pattern that provides a simplified interface to a complex subsystem. In the context of SRP, it can be used to create a unified interface for a set of classes that handle different responsibilities, thereby adhering to the principle by ensuring that changes in one part of the subsystem do not affect others.
How does the script explain the concept of a 'module' in relation to SRP?
-In the script, a 'module' is explained as a collection of classes, functions, or a package that encapsulates a set of functionalities. It should be designed in such a way that it has only one reason to change, driven by the needs of one actor or stakeholder group.
What is the significance of decomposing a class into multiple classes as per SRP?
-Decomposing a class into multiple classes as per SRP ensures that each class has a single responsibility and a single reason to change. This leads to a design where each class is focused on a specific business requirement or functionality, making the system easier to understand, maintain, and extend.
How does the script address the misconception that a class should have only one public method according to SRP?
-The script clarifies that the misconception about SRP being that a class should have only one public method is incorrect. Instead, it emphasizes that as long as the changes in a class are driven by one primary stakeholder or group of stakeholders, the class can have multiple public methods.
What are some practical examples given in the script to explain SRP?
-The script provides practical examples such as the 'Employee' class with multiple responsibilities and the 'Bill' class in a restaurant app that calculates the final amount, prints the bill, and saves the bill. These examples are used to illustrate how violating SRP can lead to issues and how decomposing these classes can resolve these issues.
Outlines
đ Understanding the Single Responsibility Principle
The paragraph introduces the concept of the Single Responsibility Principle (SRP), one of the SOLID principles of object-oriented design. It clarifies common misconceptions about SRP, emphasizing that a class should have only one reason to change, not necessarily one method. The speaker references Uncle Bob's 'Clean Code' and explains SRP using the example of an 'Employee' class with multiple methods serving different stakeholders (CFO, HR, and Engineering). The paragraph highlights how changes in one method can inadvertently affect others due to shared functionality, thus violating SRP. The solution proposed is to refactor the class into separate classes, each with a single responsibility, to ensure changes in one part of the system do not impact others.
đ Deep Dive into SRP with Real-World Examples
This paragraph delves deeper into the Single Responsibility Principle with practical examples. It uses the scenario of a restaurant app with a 'MenuItem' class and a 'Bill' class to illustrate how a class can end up handling multiple responsibilities, such as calculating the bill, printing it, and saving it. The paragraph explains how changes in one aspect, like saving the bill to a database, can affect other functionalities if not properly separated. The speaker suggests decomposing the 'Bill' class into smaller, more focused classes like 'BillPrinter' and 'BillStore' to adhere to SRP. This approach ensures that changes in one area, such as database storage, do not disrupt other functionalities like bill calculation.
đ„ Wrapping Up and Looking Forward to Open/Close Principle
In the concluding paragraph, the speaker summarizes the discussion on the Single Responsibility Principle and invites viewers to engage with any questions or doubts in the comments. The speaker also teases the next video, which will cover the Open/Close Principle, another of the SOLID principles. The paragraph serves as a bridge to upcoming content, encouraging viewers to continue their learning journey with the series.
Mindmap
Keywords
đĄSingle Responsibility Principle
đĄModule
đĄActor
đĄFacade Pattern
đĄDecomposition
đĄStakeholder
đĄBusiness Requirement
đĄDesign Patterns
đĄClean Code
đĄOpen-Close Principle
Highlights
Introduction to the Single Responsibility Principle (SRP) and its common misconceptions.
The true meaning of SRP as explained by Uncle Bob in his book 'Clean Code'.
SRP defined: A module should have one reason to change, influenced by one actor.
Explanation of the term 'actor' in the context of SRP with an example.
Example of an 'Employee' class violating SRP by serving multiple stakeholders.
Illustration of how changes in one part of a class can affect other functionalities due to shared methods.
The concept that a class should encapsulate functionalities that cater to one business functionality.
SRP does not mean a class should have only one public method.
The importance of decomposing classes to adhere to SRP for better software design.
Solution to SRP violation using the Facade pattern, although not detailed in the video.
A restaurant app example demonstrating SRP violation and its consequences.
How changes in one method can impact other methods due to shared responsibilities within a class.
The suggestion to separate concerns by creating distinct classes for different functionalities.
The idea that design is subjective and SRP should be applied based on business requirements and ease of change.
Encouragement for viewers to explore more about SRP and leave comments for further discussion.
A preview of the next video, which will cover the Open-Close Principle.
Transcripts
hello and welcome to pseudocode in this
video we are going to talk about one of
the solid principles that starts with s
which is single responsibility principle
you might have heard definitions like
single responsibility principle means
one class should have only one and one
reason to change one class should have
only one public method or if your class
description has and in the definition
that means you're breaking the single
responsibility principle and so on
i'm sorry to break the sad news to you
this is not what single responsibility
principle means
let's see actually what uncle bob meant
when he
coined the term single responsibility
principles or how he has explained in
his book so let's get started
[Music]
single responsibility principle from its
name sounds very straightforward that
one class or one module or one function
should have only one responsibility and
should have only one reason to change in
fact even i also used to think like that
but on further digging i found this book
by uncle bob it is called clean code and
i'm going to use the same example from
from his book that explains the single
responsibility principle but to start
with the definition that principle
actually states any module
module means a set of functions or a set
of functionality a class or a package or
it can be a set of functions or it can
be a source code itself
should
have a reason to change by only one
actor or the whole functionality should
be able to change by only one actor now
what does this mean here we can
understand what is the module but what
is actor here now let's try to
understand that using an example
there is a class called employee and
that class has three different methods
calculate salary calculate hours and
save employee data now that calculate
salary method can be used by actually
the financial officer of a company so
let let's call that person cfo
the hours calculate hours data can be
required by the human resources
department of the company and saving the
employee data might be required from the
technical or engineering department so
now we can see that there are three
different actors or three different
stakeholders who actually need
this functionality which is all written
in one class
now let's imagine a scenario where
calculate salary and calculate hours are
using some same underlying function or a
private function in a class
which is called get hours or get regular
hours now if there is any kind of
calculation change in the calculate
salary method which is required by the
cfo this calculation uh function will
change in this class and
it might require a change in the regular
hours private function also so the
person who is making this change uh he
or she made a change here also now two
methods public and private both have
been changed now since calculate hours
is also using this regular regular hours
method internally this implementation
breaks so cfo required a change to be
made in certain functionality and the
human resources department is getting
some wrong data because somebody changed
the underlying implementation of a
private method which was used by both
these public methods so what actually
happened here what happened here was one
class exposed two or three different
methods two or three different public
methods which were corresponding to
different stakeholders of the software
or different actors of the software one
actor does not have to know anything
about the other actor or they might not
know anything about the other actor but
still change requested from one of them
has impacted the other one now this here
is the breaking of single responsibility
principle because this module is
encapsulating the different functions of
different functionality which cater to
different actors of the system and this
is what single responsibility principle
means that the code that you are writing
if that code request changes from only
one actor or one stakeholder or even
group of one stakeholder which fulfill
one business requirement
till that point it is fine so that means
your class can have more than one public
methods as long as the change in those
public methods or change in those
business logic is requested by one
primary stakeholder or group of
stakeholders till then it is fine but if
one class has changes being requested
from different stakeholders that means
you have tried to put toward three
different business functionalities
together in one module and you have
broken the single responsibility
principle so this is what the example in
the clean code entails now how do we
solve this the best way to solve this
like in the book it has been explained
using facade pattern which i will not go
into detail here because it is still out
of scope i have not completed the design
patterns yet but a better way to do this
is to break the classes you make a
salary calculator class you make our
calculator class and you making a store
class and all those classes can be
called from different parts of the
program and the calculation of
salary does not need to know about or
does not need to depend on any method
that is used in calculate hours
similarly saving the employee data to
some database does not need to know
about calculate salary or calculate
hours at all this way while by
separating the class or by
decomposing one class into multiple
classes we can actually other to single
responsibility principle where the
business function or the business
requirement or the business logic sits
in particular classes and the request
for those requests for changing that
business logic can only come from one
particular stakeholder since all of this
can be a lot to wrap your head around
hence we will try to understand one more
simpler example let's say there is a
small restaurant app
where we have a class called menu item
now this class has the name of the item
the
if that item is available for take away
or not and the amount of the item and
tax and discount etcetera
okay now there is another class called
bill which can consist a list of these
items the
customer on whose name the bill has to
be generated the timestamp and other
properties
if you think about it the responsibility
of the bill class is to calculate the
final amount so what does this function
does it goes over all the items of the
classes get their prices applies
particular discount etc and returns the
final amount
now once the bill is generated the bill
also has to be printed and the same bill
file of the same build data also has to
be saved to some location it can be a
local file or it can be a database or
anything so there is a save function it
can seem perfectly fine to keep all
these methods in the same build class
where you are calculating the bill
printing the bill and saving the bill
now let's see what happens there is a
team who want to change the database
implementation of how the bill is being
saved maybe they want to change the data
store all together or maybe they want to
modify the columns the way in which the
bill is saved they would come and make
changes to this class now if they have
to make changes to this class they might
end up adding some more properties in
the class implementation itself and
whoever is using the constructor of this
bill class that functionality will break
because they have changed the
attributes and the basic properties of
this class itself and why did they
change it because they wanted to change
how the bill is saved in database so
again
saving something to database this
responsibility should have been catered
by a different class if let's say this
function save bill would have been in an
another class called store class and
that implementation would have been
hidden from the bill class whoever was
supposed to make that change they would
have made this change in the in that
store class itself without having to
change the any columns of the bill
similarly printing the bill that format
require that format print format might
require some changes and again if though
that change is impacting the whole bill
class it is again breaking the single
responsibility principle because so many
things are happening inside one class
and change in one method can impact
another method so it would be so the
best way would be to again decompose
these classes there can be a uh bill
printer class there can be a bill store
class and then there can be a bill class
whose sole responsibility is to
calculate the final amount of the bill
and once the final amount of bill is
calculated this bill object can be
passed on to the bill printer class and
this bill object can be passed on to the
storable class now however the store
class wants to store the data add or
remove columns or keep some data from
the bill or not keep some data from the
bill they can do it without impacting
the actual build class so this comprises
of the whole single responsibility
principle
i hope that i have explained it in a
clear manner and uh please note that
again and again i am saying that it does
not mean that one class should have only
one public method that is not the
meaning of single responsibility
principle the meaning is
module collection of classes functions
should cater changes to a particular
business stakeholder or a group of
stakeholders through which the changes
come into the picture if one class or
one module has changes coming in from
different business functions that means
something is going wrong
and as i always say design is something
which is very subjective it is not
objective there is no single right or
wrong answer to single responsibility
principle you might argue that this way
if i keep on decomposing my classes i
will end up with a lot of classes and
where do i stop again it is up to your
judgment and the business requirements
that how do you organize your classes
decompose your classes or put them
together
as long as it is fulfilling the business
requirement and it is rendering the
software easy to change as long as the
software is easy to change and it is not
breaking the existing functionality that
itself is a good signal that your design
is good i have linked the book from
which i have picked this example i have
linked other resources as well for you
to read more about this concept if you
have any doubt please please feel free
to leave it in the comments and i will
try to address it in the next video we
will understand the next solid principle
starting from o which is called open
close principle till then take care see
you in the next video
[Music]
5.0 / 5 (0 votes)