SlideShare a Scribd company logo
1 of 41
Download to read offline
S.O.L.I.D
S.O.L.I.D
• Single Responsibility
• Open/Closed
• Liskov Substitution
• Interface Segregation
• Dependency Inversion
Why?
• Create easy to maintain systems
• Improve reusability
• Easy testing
It’s all about the money
Always try to test
everything
“I don’t need to test this.”
–Michael C. Feathers, Working Effectively with Legacy Code
“Code without tests is bad code. It doesn't
matter how well written it is; it doesn't matter
how pretty or object-oriented or well-
encapsulated it is. With tests, we can change
the behavior of our code quickly and verifiably.
Without them, we really don't know if our code
is getting better or worse.”
Single Responsibility
Principle
- Robert Martin
“There should never be more than one reason
for a class to change”
class CarWashService(object):
def __init__(self, sms_sender):
self.persistence = {}
self.sms_sender = sms_sender
def require_car_wash(self, car, customer):
service_id = uuid.uuid4().hex
self.persistence[service_id] = (car, customer)
return service_id
def wash_completed(self, service_id):
car, customer = self.persistence[service_id]
self.sms_sender.send(mobile_phone=customer.mobile_phone,
text='Car %{car.plate} washed'.format(car=car))
class CarWashService(object):
def __init__(self, sms_sender):
self.persistence = {}
self.sms_sender = sms_sender
def require_car_wash(self, car, customer):
service_id = uuid.uuid4().hex
self.persistence[service_id] = (car, customer)
return service_id
def wash_completed(self, service_id):
car, customer = self.persistence[service_id]
self.sms_sender.send(mobile_phone=customer.mobile_phone,
text='Car %{car.plate} washed'.format(car=car))
class CarWashService(object):
def __init__(self, sms_sender):
self.persistence = {}
self.sms_sender = sms_sender
def require_car_wash(self, car, customer):
service_id = uuid.uuid4().hex
self.persistence[service_id] = (car, customer)
return service_id
def wash_completed(self, service_id):
car, customer = self.persistence[service_id]
self.sms_sender.send(mobile_phone=customer.mobile_phone,
text='Car %{car.plate} washed'.format(car=car))
class CarWashService(object):
def __init__(self, notifier, repository):
self.repository = repository
self.notifier = notifier
def enter_in_the_car_wash(self, car, customer):
job = CarWashJob(car, customer)
self.repository.put(job)
return job
def wash_completed(self, service_id):
car_wash_job = self.repository.find_by_id(service_id)
self.notifier.job_completed(car_wash_job)
Dependency Inversion
Principle
class CarWashService(object):
def __init__(self, repository):
self.repository = repository
def enter_the_car_wash(self, car, customer):
job = CarWashJob(car, customer)
self.repository.put(job)
return job
def wash_completed(self, service_id):
car_wash_job = self.repository.find_by_id(service_id)
SmsNotifier.send_sms(car_wash_job)
Would you solder a lamp
directly to the wiring in a
wall?
Depend upon
abstraction. Do not
depend upon concretion
class CarWashService(object):
def __init__(self, notifier, repository):
self.repository = repository
self.notifier = notifier
def enter_the_car_wash(self, car, customer):
job = CarWashJob(car, customer)
self.repository.put(job)
return job
def wash_completed(self, service_id):
car_wash_job = self.repository.find_by_id(service_id)
self.notifier.job_completed(car_wash_job)
Open Closed Principle
Open chest surgery isn’t
needed when putting a
coat
class JobRepository(object):
def __init__(self, type):
self.type = type
def put(self, job):
if(type == ‘in_memory'):
# WOW, SUCH CODE
self.memory = {}
elif(type == 'database'):
self.memory = Database.connect()
# MUCH SOURCE
Ifs and else’s are not a sign of problem
complexity. They are a sign of code complexity
class IJobRepository(object):
def put(self, job):
raise NotImplementedError()
class InMemoryJobRepository(IJobRepository):
def __init__(self):
self._storage = {}
def put(self, job)
self._storage[job.service_id] = job
Liskov Substituion
Principle
- Barbara Liskov
“Let phi(x) be a property provable about
objects x of type T. Then phi(y) should be true
for objects y of type S where S is a subtype of
T.”
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def area(self):
return self.height * self.height
def much_code():
my_shape = factory.rectangle(10, 5)
my_shape.area() # I expect this to be 50
If you change the references
from base classes to child
classes, the tests should pass.
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Square(Rectangle):
def area(self):
return self.height * self.height
def much_code():
my_shape = factory.rectangle(10, 5)
my_shape.area() # I expect this to be 50
Square is not a subtype of Rectangle
Interface Segregation
Principle
Always prefer small
interfaces (contracts)
Several interfaces are
better than one big one
Solid presentation yo

More Related Content

Similar to Solid presentation yo

Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
davismr
 
AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
Miklos Csere
 
The Taming Of The Code
The Taming Of The CodeThe Taming Of The Code
The Taming Of The Code
Alan Stevens
 

Similar to Solid presentation yo (20)

Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
 
Refactor your way forward
Refactor your way forwardRefactor your way forward
Refactor your way forward
 
"S"OLID Principles - Single responsibility principle
"S"OLID Principles - Single responsibility principle"S"OLID Principles - Single responsibility principle
"S"OLID Principles - Single responsibility principle
 
Ruby On Rails Pitfalls
Ruby On Rails PitfallsRuby On Rails Pitfalls
Ruby On Rails Pitfalls
 
Čtvrtkon #53 - Štěpán Zikmund
Čtvrtkon #53 - Štěpán ZikmundČtvrtkon #53 - Štěpán Zikmund
Čtvrtkon #53 - Štěpán Zikmund
 
Deciphering the Ruby Object Model
Deciphering the Ruby Object ModelDeciphering the Ruby Object Model
Deciphering the Ruby Object Model
 
Thinking In Swift
Thinking In SwiftThinking In Swift
Thinking In Swift
 
Bdd with Cucumber and Mocha
Bdd with Cucumber and MochaBdd with Cucumber and Mocha
Bdd with Cucumber and Mocha
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
 
Javascript for the c# developer
Javascript for the c# developerJavascript for the c# developer
Javascript for the c# developer
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia InstituteMVC Design Pattern in JavaScript by ADMEC Multimedia Institute
MVC Design Pattern in JavaScript by ADMEC Multimedia Institute
 
Boost delivery stream with code discipline engineering
Boost delivery stream with code discipline engineeringBoost delivery stream with code discipline engineering
Boost delivery stream with code discipline engineering
 
First class Variables in Pharo
First class Variables in PharoFirst class Variables in Pharo
First class Variables in Pharo
 
Variables in Pharo5
Variables in Pharo5Variables in Pharo5
Variables in Pharo5
 
The Taming Of The Code
The Taming Of The CodeThe Taming Of The Code
The Taming Of The Code
 
2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#2009 Dotnet Information Day: More effective c#
2009 Dotnet Information Day: More effective c#
 
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019
 

Recently uploaded

JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
Max Lee
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 

Recently uploaded (20)

The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion Production
 
IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024IT Software Development Resume, Vaibhav jha 2024
IT Software Development Resume, Vaibhav jha 2024
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
 
Workforce Efficiency with Employee Time Tracking Software.pdf
Workforce Efficiency with Employee Time Tracking Software.pdfWorkforce Efficiency with Employee Time Tracking Software.pdf
Workforce Efficiency with Employee Time Tracking Software.pdf
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdfImplementing KPIs and Right Metrics for Agile Delivery Teams.pdf
Implementing KPIs and Right Metrics for Agile Delivery Teams.pdf
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in Michelangelo
 
5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
How to pick right visual testing tool.pdf
How to pick right visual testing tool.pdfHow to pick right visual testing tool.pdf
How to pick right visual testing tool.pdf
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
APVP,apvp apvp High quality supplier safe spot transport, 98% purity
APVP,apvp apvp High quality supplier safe spot transport, 98% purityAPVP,apvp apvp High quality supplier safe spot transport, 98% purity
APVP,apvp apvp High quality supplier safe spot transport, 98% purity
 
10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf10 Essential Software Testing Tools You Need to Know About.pdf
10 Essential Software Testing Tools You Need to Know About.pdf
 
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
KLARNA -  Language Models and Knowledge Graphs: A Systems ApproachKLARNA -  Language Models and Knowledge Graphs: A Systems Approach
KLARNA - Language Models and Knowledge Graphs: A Systems Approach
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
INGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignINGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by Design
 
how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdf
 

Solid presentation yo

  • 2. S.O.L.I.D • Single Responsibility • Open/Closed • Liskov Substitution • Interface Segregation • Dependency Inversion
  • 4. • Create easy to maintain systems • Improve reusability • Easy testing
  • 5.
  • 6. It’s all about the money
  • 7. Always try to test everything
  • 8. “I don’t need to test this.”
  • 9. –Michael C. Feathers, Working Effectively with Legacy Code “Code without tests is bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well- encapsulated it is. With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse.”
  • 10.
  • 12. - Robert Martin “There should never be more than one reason for a class to change”
  • 13. class CarWashService(object): def __init__(self, sms_sender): self.persistence = {} self.sms_sender = sms_sender def require_car_wash(self, car, customer): service_id = uuid.uuid4().hex self.persistence[service_id] = (car, customer) return service_id def wash_completed(self, service_id): car, customer = self.persistence[service_id] self.sms_sender.send(mobile_phone=customer.mobile_phone, text='Car %{car.plate} washed'.format(car=car))
  • 14. class CarWashService(object): def __init__(self, sms_sender): self.persistence = {} self.sms_sender = sms_sender def require_car_wash(self, car, customer): service_id = uuid.uuid4().hex self.persistence[service_id] = (car, customer) return service_id def wash_completed(self, service_id): car, customer = self.persistence[service_id] self.sms_sender.send(mobile_phone=customer.mobile_phone, text='Car %{car.plate} washed'.format(car=car))
  • 15. class CarWashService(object): def __init__(self, sms_sender): self.persistence = {} self.sms_sender = sms_sender def require_car_wash(self, car, customer): service_id = uuid.uuid4().hex self.persistence[service_id] = (car, customer) return service_id def wash_completed(self, service_id): car, customer = self.persistence[service_id] self.sms_sender.send(mobile_phone=customer.mobile_phone, text='Car %{car.plate} washed'.format(car=car))
  • 16.
  • 17. class CarWashService(object): def __init__(self, notifier, repository): self.repository = repository self.notifier = notifier def enter_in_the_car_wash(self, car, customer): job = CarWashJob(car, customer) self.repository.put(job) return job def wash_completed(self, service_id): car_wash_job = self.repository.find_by_id(service_id) self.notifier.job_completed(car_wash_job)
  • 19. class CarWashService(object): def __init__(self, repository): self.repository = repository def enter_the_car_wash(self, car, customer): job = CarWashJob(car, customer) self.repository.put(job) return job def wash_completed(self, service_id): car_wash_job = self.repository.find_by_id(service_id) SmsNotifier.send_sms(car_wash_job)
  • 20. Would you solder a lamp directly to the wiring in a wall?
  • 21. Depend upon abstraction. Do not depend upon concretion
  • 22. class CarWashService(object): def __init__(self, notifier, repository): self.repository = repository self.notifier = notifier def enter_the_car_wash(self, car, customer): job = CarWashJob(car, customer) self.repository.put(job) return job def wash_completed(self, service_id): car_wash_job = self.repository.find_by_id(service_id) self.notifier.job_completed(car_wash_job)
  • 24. Open chest surgery isn’t needed when putting a coat
  • 25. class JobRepository(object): def __init__(self, type): self.type = type def put(self, job): if(type == ‘in_memory'): # WOW, SUCH CODE self.memory = {} elif(type == 'database'): self.memory = Database.connect() # MUCH SOURCE
  • 26.
  • 27. Ifs and else’s are not a sign of problem complexity. They are a sign of code complexity
  • 28. class IJobRepository(object): def put(self, job): raise NotImplementedError() class InMemoryJobRepository(IJobRepository): def __init__(self): self._storage = {} def put(self, job) self._storage[job.service_id] = job
  • 30.
  • 31. - Barbara Liskov “Let phi(x) be a property provable about objects x of type T. Then phi(y) should be true for objects y of type S where S is a subtype of T.”
  • 32. class Rectangle(object): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Square(Rectangle): def area(self): return self.height * self.height def much_code(): my_shape = factory.rectangle(10, 5) my_shape.area() # I expect this to be 50
  • 33. If you change the references from base classes to child classes, the tests should pass.
  • 34.
  • 35. class Rectangle(object): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Square(Rectangle): def area(self): return self.height * self.height def much_code(): my_shape = factory.rectangle(10, 5) my_shape.area() # I expect this to be 50
  • 36. Square is not a subtype of Rectangle
  • 38.
  • 40. Several interfaces are better than one big one