SlideShare a Scribd company logo
“S”OLID - Single
Responsibility Principle
- By Nishant Upadhyay @TuesdayTalks
What’s SOLID Principle?
It’s a set of 5 principles which when followed will result into a program which is
being much more easy to maintain, is bug free, and faster to develop.
SOLID consist of the following principles:
1. Single responsibility
2. Open-closed
3. Liskov substitution
4. Interface segregation
5. and Dependency inversion
When SOLID principle emerge?
- Programming is all about breaking problems down into parts.
- There's lots of ways to break down code
- For example, The close button - Object that’s responsible for close button vs
The object that’s responsible for all read buttons. Which one is more relevant?
- Programmers worked out rules for how to organize their code so it would be
easy to reuse or change. One set of rules is called "SOLID". Every letter stands
for a different principle.
- SOLID is a set of rules that's probably a good idea to follow, but you won't
instantly get into trouble if you break it. You'll see a lot of these as you grow
up.
Why should we care about “SOLID”?
Benefits of using SOLID in your programming.
1. Easy to maintain
2. Easy to extend
3. Robust code
Coupling and Cohesion
Remember two relevant concepts in the development of any software
1. Coupling - The degree to which a class, method or any other software entity, is
directly linked to another, Dependency.
Example: If two classes are tightly coupled then changes in one class may
require lots of changes in another class.
1. Cohesion - Cohesion is a degree (quality) to which a component / module
focuses on the single thing.
Example : A well focused class, Use of modules, packages, libraries
The “S” of SOLID - Single Responsibility
Our objects should only solve one problem. When they do too many things they get
confused, so let's keep them as simple as possible.
Benefits:
● Coupling reduced.
● Code easier to understand and maintain
A class should have only a single responsibility.
OR
A class should have only one reason to change.
Let’s understand “S” by example
Usage of APIs are very common now. Let's say we need to call BlogService to get
list of blog posts.
So two corresponding classes here:
BlogService and Post
Let’s see some code now..
Let’s identify responsibilities
1. Configuration
url = 'https://jsonplaceholder.typicode.com/posts'
url = 'https://prod.myserver.com' if env == 'production'
2. Logging
puts "[BlogService] GET #{url}"
3. HTTP Layer
response = Net::HTTP.get_response(URI(url))
return [] if response.code != '200'
4. Response processing.
Assume we will get response like given below:
posts = JSON.parse(response.body)
posts.map do |params|
Post.new(
id: params['id'],
user_id: params['userId'],
body: params['body'],
title: params['title']
)
end
So At least 4 responsibilities for one class!
Let's try to follow this rule and refactor the code
Extract configuration part into separate class:
class BlogServiceConfig
def initialize(env:)
@env = env
end
def base_url
return 'https://prod.myserver.com' if @env == 'production'
'https://jsonplaceholder.typicode.com'
end
end
Now we can use this class in BlogService:
class BlogService
# ...
def posts
url = "#{config.base_url}/posts"
puts "[BlogService] GET #{url}"
response = Net::HTTP.get_response(URI(url))
# ...
end
private
# ...
def config
@config ||= BlogServiceConfig.new(env: @env)
end
end
Let's move forward and extract logging
module RequestLogger
def log_request(service, url, method = 'GET')
puts "[#{service}] #{method} #{url}"
end
end
class BlogService
include RequestLogger
# ...
def posts
url = "#{config.base_url}/posts"
log_request('BlogService', url)
response = Net::HTTP.get_response(URI(url))
# ...
end
end
We've extracted 2 classes so far. Now we need to
figure out how to handle HTTP layer and
response processing.
Implementing HTTP request handler
class RequestHandler
ResponseError = Class.new(StandardError)
def send_request(url, method = :get)
response = Net::HTTP.get_response(URI(url))
raise ResponseError if response.code != '200'
JSON.parse(response.body)
end
end
Let's send API call using RequestHandler:
class BlogService
# ...
def posts
url = "#{config.base_url}/posts"
log_request('BlogService', url)
posts = request_handler.send_request(url)
# ...
end
private
# ...
def request_handler
@request_handler ||= RequestHandler.new
end
end
ResponseProcessor to process response
class ResponseProcessor
def process(response, entity)
return entity.new(response) if response.is_a?(Hash)
if response.is_a?(Array)
response.map { |h| entity.new(h) if h.is_a?(Hash) }
end
end
end
Now, we can use the processor in our main class:
class BlogService
# ...
def posts
url = "#{config.base_url}/posts"
log_request('BlogService', url)
posts = request_handler.send_request(url)
response_processor.process(posts, Post)
end
private
# ...
def response_processor
@response_processor ||= ResponseProcessor.new
end
end
Method posts looks much smaller now and we can read some boring code there:
1. Construct url
2. Log request
3. Send request
4. Process response
Still one problem!
In initial implementation we had sort of mapping between fields:
Post.new(
id: params['id'],
user_id: params['userId'],
body: params['body'],
title: params['title']
)
Let’s make it more flexible!
class ResponseProcessor
def process(response, entity, mapping = {})
return entity.new(map(response, mapping)) if response.is_a?(Hash)
if response.is_a?(Array)
response.map { |h| entity.new(map(h, mapping)) if h.is_a?(Hash) }
end
end
def map(params, mapping = {})
return params if mapping.empty?
params.each_with_object({}) do |(k, v), hash|
hash[mapping[k] ? mapping[k] : k] = v
end
end
end
Let's check final result.
Let’s add another method and see how it works!
def post(id)
url = "#{config.base_url}/posts/#{id}"
log_request('BlogService', url)
posts = request_handler.send_request(url)
response_processor.process(posts, Post, mapping)
end
As you see without any significant change, We
are able to add a method easily.!!!
This is the beauty of Single Responsibility Rule!
“Your actions become your habits,
Your habits become your values,
Your values become your destiny.”
- Mahatma Gandhi
My point is to always strive to be better by challenging
yourself. At some point, you will ask, but you will know already
the answer…
"S"OLID Principles - Single responsibility principle

More Related Content

Similar to "S"OLID Principles - Single responsibility principle

Software design principles - jinal desai
Software design principles - jinal desaiSoftware design principles - jinal desai
Software design principles - jinal desai
jinaldesailive
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptx
Stefan Oprea
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
Srinivasa GV
 
Tdd is not about testing
Tdd is not about testingTdd is not about testing
Tdd is not about testing
Gianluca Padovani
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
Cory Foy
 
C#.net interview questions for dynamics 365 ce crm developers
C#.net interview questions for dynamics 365 ce crm developersC#.net interview questions for dynamics 365 ce crm developers
C#.net interview questions for dynamics 365 ce crm developers
Sanjaya Prakash Pradhan
 
Ad507
Ad507Ad507
Spring boot
Spring bootSpring boot
Zend Framework And Doctrine
Zend Framework And DoctrineZend Framework And Doctrine
Zend Framework And Doctrine
isaaczfoster
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
Graham Dumpleton
 
OOP-Advanced Programming with c++
OOP-Advanced Programming with c++OOP-Advanced Programming with c++
OOP-Advanced Programming with c++
Mohamed Essam
 
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Tekblink Jeeten
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin
Vasil Remeniuk
 
Java interview questions and answers
Java interview questions and answersJava interview questions and answers
Java interview questions and answers
Krishnaov
 
Solid principles
Solid principlesSolid principles
Solid principles
Toan Nguyen
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
Romain Rochegude
 
Nt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language AnalysisNt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language Analysis
Nicole Gomez
 
Sec1_SOLID Principles_Software Engineering.pptx
Sec1_SOLID Principles_Software Engineering.pptxSec1_SOLID Principles_Software Engineering.pptx
Sec1_SOLID Principles_Software Engineering.pptx
HebaSamy22
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test Automaion
Knoldus Inc.
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
rstankov
 

Similar to "S"OLID Principles - Single responsibility principle (20)

Software design principles - jinal desai
Software design principles - jinal desaiSoftware design principles - jinal desai
Software design principles - jinal desai
 
Web technologies-course 12.pptx
Web technologies-course 12.pptxWeb technologies-course 12.pptx
Web technologies-course 12.pptx
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 
Tdd is not about testing
Tdd is not about testingTdd is not about testing
Tdd is not about testing
 
Ruby for C# Developers
Ruby for C# DevelopersRuby for C# Developers
Ruby for C# Developers
 
C#.net interview questions for dynamics 365 ce crm developers
C#.net interview questions for dynamics 365 ce crm developersC#.net interview questions for dynamics 365 ce crm developers
C#.net interview questions for dynamics 365 ce crm developers
 
Ad507
Ad507Ad507
Ad507
 
Spring boot
Spring bootSpring boot
Spring boot
 
Zend Framework And Doctrine
Zend Framework And DoctrineZend Framework And Doctrine
Zend Framework And Doctrine
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
OOP-Advanced Programming with c++
OOP-Advanced Programming with c++OOP-Advanced Programming with c++
OOP-Advanced Programming with c++
 
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin
 
Java interview questions and answers
Java interview questions and answersJava interview questions and answers
Java interview questions and answers
 
Solid principles
Solid principlesSolid principles
Solid principles
 
iOS Swift application architecture
iOS Swift application architectureiOS Swift application architecture
iOS Swift application architecture
 
Nt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language AnalysisNt1310 Unit 3 Language Analysis
Nt1310 Unit 3 Language Analysis
 
Sec1_SOLID Principles_Software Engineering.pptx
Sec1_SOLID Principles_Software Engineering.pptxSec1_SOLID Principles_Software Engineering.pptx
Sec1_SOLID Principles_Software Engineering.pptx
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test Automaion
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 

Recently uploaded

OOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming languageOOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming language
PreethaV16
 
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
ydzowc
 
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
GiselleginaGloria
 
SELENIUM CONF -PALLAVI SHARMA - 2024.pdf
SELENIUM CONF -PALLAVI SHARMA - 2024.pdfSELENIUM CONF -PALLAVI SHARMA - 2024.pdf
SELENIUM CONF -PALLAVI SHARMA - 2024.pdf
Pallavi Sharma
 
Properties of Fluids, Fluid Statics, Pressure Measurement
Properties of Fluids, Fluid Statics, Pressure MeasurementProperties of Fluids, Fluid Statics, Pressure Measurement
Properties of Fluids, Fluid Statics, Pressure Measurement
Indrajeet sahu
 
Beckhoff Programmable Logic Control Overview Presentation
Beckhoff Programmable Logic Control Overview PresentationBeckhoff Programmable Logic Control Overview Presentation
Beckhoff Programmable Logic Control Overview Presentation
VanTuDuong1
 
Call Girls Chennai +91-8824825030 Vip Call Girls Chennai
Call Girls Chennai +91-8824825030 Vip Call Girls ChennaiCall Girls Chennai +91-8824825030 Vip Call Girls Chennai
Call Girls Chennai +91-8824825030 Vip Call Girls Chennai
paraasingh12 #V08
 
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICSUNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
vmspraneeth
 
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEERDELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
EMERSON EDUARDO RODRIGUES
 
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
sydezfe
 
Ericsson LTE Throughput Troubleshooting Techniques.ppt
Ericsson LTE Throughput Troubleshooting Techniques.pptEricsson LTE Throughput Troubleshooting Techniques.ppt
Ericsson LTE Throughput Troubleshooting Techniques.ppt
wafawafa52
 
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
Sou Tibon
 
openshift technical overview - Flow of openshift containerisatoin
openshift technical overview - Flow of openshift containerisatoinopenshift technical overview - Flow of openshift containerisatoin
openshift technical overview - Flow of openshift containerisatoin
snaprevwdev
 
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
Paris Salesforce Developer Group
 
Unit -II Spectroscopy - EC I B.Tech.pdf
Unit -II Spectroscopy - EC  I B.Tech.pdfUnit -II Spectroscopy - EC  I B.Tech.pdf
Unit -II Spectroscopy - EC I B.Tech.pdf
TeluguBadi
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
uqyfuc
 
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
upoux
 
This study Examines the Effectiveness of Talent Procurement through the Imple...
This study Examines the Effectiveness of Talent Procurement through the Imple...This study Examines the Effectiveness of Talent Procurement through the Imple...
This study Examines the Effectiveness of Talent Procurement through the Imple...
DharmaBanothu
 
paper relate Chozhavendhan et al. 2020.pdf
paper relate Chozhavendhan et al. 2020.pdfpaper relate Chozhavendhan et al. 2020.pdf
paper relate Chozhavendhan et al. 2020.pdf
ShurooqTaib
 
Determination of Equivalent Circuit parameters and performance characteristic...
Determination of Equivalent Circuit parameters and performance characteristic...Determination of Equivalent Circuit parameters and performance characteristic...
Determination of Equivalent Circuit parameters and performance characteristic...
pvpriya2
 

Recently uploaded (20)

OOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming languageOOPS_Lab_Manual - programs using C++ programming language
OOPS_Lab_Manual - programs using C++ programming language
 
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
原版制作(Humboldt毕业证书)柏林大学毕业证学位证一模一样
 
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
3rd International Conference on Artificial Intelligence Advances (AIAD 2024)
 
SELENIUM CONF -PALLAVI SHARMA - 2024.pdf
SELENIUM CONF -PALLAVI SHARMA - 2024.pdfSELENIUM CONF -PALLAVI SHARMA - 2024.pdf
SELENIUM CONF -PALLAVI SHARMA - 2024.pdf
 
Properties of Fluids, Fluid Statics, Pressure Measurement
Properties of Fluids, Fluid Statics, Pressure MeasurementProperties of Fluids, Fluid Statics, Pressure Measurement
Properties of Fluids, Fluid Statics, Pressure Measurement
 
Beckhoff Programmable Logic Control Overview Presentation
Beckhoff Programmable Logic Control Overview PresentationBeckhoff Programmable Logic Control Overview Presentation
Beckhoff Programmable Logic Control Overview Presentation
 
Call Girls Chennai +91-8824825030 Vip Call Girls Chennai
Call Girls Chennai +91-8824825030 Vip Call Girls ChennaiCall Girls Chennai +91-8824825030 Vip Call Girls Chennai
Call Girls Chennai +91-8824825030 Vip Call Girls Chennai
 
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICSUNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
UNIT 4 LINEAR INTEGRATED CIRCUITS-DIGITAL ICS
 
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEERDELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
DELTA V MES EMERSON EDUARDO RODRIGUES ENGINEER
 
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
一比一原版(uoft毕业证书)加拿大多伦多大学毕业证如何办理
 
Ericsson LTE Throughput Troubleshooting Techniques.ppt
Ericsson LTE Throughput Troubleshooting Techniques.pptEricsson LTE Throughput Troubleshooting Techniques.ppt
Ericsson LTE Throughput Troubleshooting Techniques.ppt
 
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
309475979-Creativity-Innovation-notes-IV-Sem-2016-pdf.pdf
 
openshift technical overview - Flow of openshift containerisatoin
openshift technical overview - Flow of openshift containerisatoinopenshift technical overview - Flow of openshift containerisatoin
openshift technical overview - Flow of openshift containerisatoin
 
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
AI + Data Community Tour - Build the Next Generation of Apps with the Einstei...
 
Unit -II Spectroscopy - EC I B.Tech.pdf
Unit -II Spectroscopy - EC  I B.Tech.pdfUnit -II Spectroscopy - EC  I B.Tech.pdf
Unit -II Spectroscopy - EC I B.Tech.pdf
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
一比一原版(osu毕业证书)美国俄勒冈州立大学毕业证如何办理
 
This study Examines the Effectiveness of Talent Procurement through the Imple...
This study Examines the Effectiveness of Talent Procurement through the Imple...This study Examines the Effectiveness of Talent Procurement through the Imple...
This study Examines the Effectiveness of Talent Procurement through the Imple...
 
paper relate Chozhavendhan et al. 2020.pdf
paper relate Chozhavendhan et al. 2020.pdfpaper relate Chozhavendhan et al. 2020.pdf
paper relate Chozhavendhan et al. 2020.pdf
 
Determination of Equivalent Circuit parameters and performance characteristic...
Determination of Equivalent Circuit parameters and performance characteristic...Determination of Equivalent Circuit parameters and performance characteristic...
Determination of Equivalent Circuit parameters and performance characteristic...
 

"S"OLID Principles - Single responsibility principle

  • 1. “S”OLID - Single Responsibility Principle - By Nishant Upadhyay @TuesdayTalks
  • 2. What’s SOLID Principle? It’s a set of 5 principles which when followed will result into a program which is being much more easy to maintain, is bug free, and faster to develop. SOLID consist of the following principles: 1. Single responsibility 2. Open-closed 3. Liskov substitution 4. Interface segregation 5. and Dependency inversion
  • 3. When SOLID principle emerge? - Programming is all about breaking problems down into parts. - There's lots of ways to break down code - For example, The close button - Object that’s responsible for close button vs The object that’s responsible for all read buttons. Which one is more relevant? - Programmers worked out rules for how to organize their code so it would be easy to reuse or change. One set of rules is called "SOLID". Every letter stands for a different principle. - SOLID is a set of rules that's probably a good idea to follow, but you won't instantly get into trouble if you break it. You'll see a lot of these as you grow up.
  • 4. Why should we care about “SOLID”? Benefits of using SOLID in your programming. 1. Easy to maintain 2. Easy to extend 3. Robust code
  • 5. Coupling and Cohesion Remember two relevant concepts in the development of any software 1. Coupling - The degree to which a class, method or any other software entity, is directly linked to another, Dependency. Example: If two classes are tightly coupled then changes in one class may require lots of changes in another class. 1. Cohesion - Cohesion is a degree (quality) to which a component / module focuses on the single thing. Example : A well focused class, Use of modules, packages, libraries
  • 6.
  • 7. The “S” of SOLID - Single Responsibility Our objects should only solve one problem. When they do too many things they get confused, so let's keep them as simple as possible. Benefits: ● Coupling reduced. ● Code easier to understand and maintain A class should have only a single responsibility. OR A class should have only one reason to change.
  • 8.
  • 9. Let’s understand “S” by example Usage of APIs are very common now. Let's say we need to call BlogService to get list of blog posts. So two corresponding classes here: BlogService and Post Let’s see some code now..
  • 10. Let’s identify responsibilities 1. Configuration url = 'https://jsonplaceholder.typicode.com/posts' url = 'https://prod.myserver.com' if env == 'production'
  • 11. 2. Logging puts "[BlogService] GET #{url}" 3. HTTP Layer response = Net::HTTP.get_response(URI(url)) return [] if response.code != '200'
  • 12. 4. Response processing. Assume we will get response like given below:
  • 13. posts = JSON.parse(response.body) posts.map do |params| Post.new( id: params['id'], user_id: params['userId'], body: params['body'], title: params['title'] ) end
  • 14. So At least 4 responsibilities for one class!
  • 15. Let's try to follow this rule and refactor the code
  • 16. Extract configuration part into separate class: class BlogServiceConfig def initialize(env:) @env = env end def base_url return 'https://prod.myserver.com' if @env == 'production' 'https://jsonplaceholder.typicode.com' end end
  • 17. Now we can use this class in BlogService: class BlogService # ... def posts url = "#{config.base_url}/posts" puts "[BlogService] GET #{url}" response = Net::HTTP.get_response(URI(url)) # ... end private # ... def config @config ||= BlogServiceConfig.new(env: @env) end end
  • 18. Let's move forward and extract logging module RequestLogger def log_request(service, url, method = 'GET') puts "[#{service}] #{method} #{url}" end end
  • 19. class BlogService include RequestLogger # ... def posts url = "#{config.base_url}/posts" log_request('BlogService', url) response = Net::HTTP.get_response(URI(url)) # ... end end
  • 20. We've extracted 2 classes so far. Now we need to figure out how to handle HTTP layer and response processing.
  • 21. Implementing HTTP request handler class RequestHandler ResponseError = Class.new(StandardError) def send_request(url, method = :get) response = Net::HTTP.get_response(URI(url)) raise ResponseError if response.code != '200' JSON.parse(response.body) end end
  • 22. Let's send API call using RequestHandler: class BlogService # ... def posts url = "#{config.base_url}/posts" log_request('BlogService', url) posts = request_handler.send_request(url) # ... end private # ... def request_handler @request_handler ||= RequestHandler.new end end
  • 23. ResponseProcessor to process response class ResponseProcessor def process(response, entity) return entity.new(response) if response.is_a?(Hash) if response.is_a?(Array) response.map { |h| entity.new(h) if h.is_a?(Hash) } end end end
  • 24. Now, we can use the processor in our main class: class BlogService # ... def posts url = "#{config.base_url}/posts" log_request('BlogService', url) posts = request_handler.send_request(url) response_processor.process(posts, Post) end private # ... def response_processor @response_processor ||= ResponseProcessor.new end end
  • 25. Method posts looks much smaller now and we can read some boring code there: 1. Construct url 2. Log request 3. Send request 4. Process response
  • 26. Still one problem! In initial implementation we had sort of mapping between fields: Post.new( id: params['id'], user_id: params['userId'], body: params['body'], title: params['title'] )
  • 27. Let’s make it more flexible! class ResponseProcessor def process(response, entity, mapping = {}) return entity.new(map(response, mapping)) if response.is_a?(Hash) if response.is_a?(Array) response.map { |h| entity.new(map(h, mapping)) if h.is_a?(Hash) } end end def map(params, mapping = {}) return params if mapping.empty? params.each_with_object({}) do |(k, v), hash| hash[mapping[k] ? mapping[k] : k] = v end end end
  • 28. Let's check final result.
  • 29. Let’s add another method and see how it works! def post(id) url = "#{config.base_url}/posts/#{id}" log_request('BlogService', url) posts = request_handler.send_request(url) response_processor.process(posts, Post, mapping) end
  • 30. As you see without any significant change, We are able to add a method easily.!!! This is the beauty of Single Responsibility Rule!
  • 31. “Your actions become your habits, Your habits become your values, Your values become your destiny.” - Mahatma Gandhi
  • 32. My point is to always strive to be better by challenging yourself. At some point, you will ask, but you will know already the answer…

Editor's Notes

  1. As you can see fat interfaces lead to inadvertent coupling between classes and you should avoid them. When designing interfaces you should always ask yourself the question “Do really need all the methods on this interface I’m using? If not how can I break them into smaller interfaces?”. If you do the right thing every and allow only the good patterns to emerge from your architecture, it will become a habit. And that it will become your values or principles. If you keep doing that it will become your destiny, which is to always produce sound solutions or whatever your idea of a software engineer is.