SlideShare a Scribd company logo
1 of 37
Download to read offline
CODE SMELLS
O QUE É UM
CODE SMELL?
LEONARDO BERNARDELLI
@lbenardelli
•Long Method
•Large Class
•Primitive Obsession
•Long Parameter List
•Data Clumps
•Switch Statements
•Temporary Field
•Refused Bequest
•Alternative Classes with Different Interfaces
•Divergent Change
•Shotgun Surgery
•Parallel Inheritance Hierarchies
•Comments
•Duplicate Code
•Lazy Class
•Data Class
•Dead Code
•Speculative Generality
•Feature Envy
•Inappropriate Intimacy
•Message Chains
•Middle Man
•Incomplete Library Class
BLOATERS
OO ABUSERS
CHANGE PREVENTERS
DISPENSABLES
COUPLERS
RefactoringPara todo existe uma receita
CODE SMELL
que explica como resolver o problema
http://www.industriallogic.com/wp-content/uploads/2005/09/smellstorefactorings.pdf
class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range =
@orders.select { |order| order.placed_at >= @start_date &&
order.placed_at <= @end_date }
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
end
class Order < OpenStruct
end
class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_at >= @start_date &&
order.placed_at <= @end_date }
end
end
class Order < OpenStruct
end
class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@start_date, @end_date) }
end
end
class Order < OpenStruct
def placed_between?(start_date, end_date)
placed_at >= start_date && placed_at <= end_date
end
end
class OrdersReport
def initialize(orders, date_range)
@orders = orders
@date_range = date_range
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@date_range) }
end
end
class DateRange < Struct.new(:start_date, :end_date)
end
class Order < OpenStruct
def placed_between?(date_range)
placed_at >= date_range.start_date && placed_at <= date_range.end_date
end
end
class OrdersReport
def initialize(orders, date_range)
@orders = orders
@date_range = date_range
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@date_range) }
end
end
class DateRange < Struct.new(:start_date, :end_date)
def include?(date)
(start_date..end_date).cover?(date)
end
end
class Order < OpenStruct
def placed_between?(date_range)
date_range.include?(placed_at)
end
end
Foo Sale
Sale
where
.where(date: range)
Persistence
where
List
a List
a List
sum
.sum('cost')
Colaboradores Imediatos
Foo
DateRange
LIST
Sale
#where
I KNOW MY COLLABORATORS COLLABORATORS
SPECULATIVE GENERALITYDEPENDENCY INJECTION
É FODA!
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.
…
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
A satisfactory modular decomposition technique must satisfy one more requirement: It should yield
modules that are both open and closed.
• A module will be said to be open if it is available for extension. For example, it should be possible to add
fields to the data structures it contains, or new elements to the set of functions it performs.
• A module will be said to be closed if is available for use by other modules. This assumes that the module
has been given a well-defined, stable description (the interface in the sense of information hiding). In the
case of a programming language module, a closed module is one that may be compiled and stored in a
library, for others to use. In the case of a design or specification module, closing a module simply means
having it approved by management, adding it to the project's official repository of accepted software
items (often called the project baseline), and publishing its interface for the benefit of other module
designers.
Robert C. Martin
SOLID
OBRIGADO!

More Related Content

What's hot

Control Structures in Visual Basic
Control Structures in  Visual BasicControl Structures in  Visual Basic
Control Structures in Visual Basic
Tushar Jain
 
Generics Tutorial
Generics TutorialGenerics Tutorial
Generics Tutorial
wasntgosu
 
9781439035665 ppt ch03
9781439035665 ppt ch039781439035665 ppt ch03
9781439035665 ppt ch03
Terry Yoast
 
Visual studio2012 tipsandtricks
Visual studio2012 tipsandtricksVisual studio2012 tipsandtricks
Visual studio2012 tipsandtricks
Tung Nguyen Thanh
 

What's hot (18)

Coding conventions
Coding conventionsCoding conventions
Coding conventions
 
Coding conventions
Coding conventionsCoding conventions
Coding conventions
 
Fundamentals of programming)
Fundamentals of programming)Fundamentals of programming)
Fundamentals of programming)
 
Naming Standards, Clean Code
Naming Standards, Clean CodeNaming Standards, Clean Code
Naming Standards, Clean Code
 
Switch statement
Switch statementSwitch statement
Switch statement
 
Switch case and looping
Switch case and loopingSwitch case and looping
Switch case and looping
 
maXbox Starter 31 Closures
maXbox Starter 31 ClosuresmaXbox Starter 31 Closures
maXbox Starter 31 Closures
 
JavaScript: Core Part
JavaScript: Core PartJavaScript: Core Part
JavaScript: Core Part
 
Lesson 02 python keywords and identifiers
Lesson 02   python keywords and identifiersLesson 02   python keywords and identifiers
Lesson 02 python keywords and identifiers
 
Refactoring: Improve the design of existing code
Refactoring: Improve the design of existing codeRefactoring: Improve the design of existing code
Refactoring: Improve the design of existing code
 
Control Structures in Visual Basic
Control Structures in  Visual BasicControl Structures in  Visual Basic
Control Structures in Visual Basic
 
Python
PythonPython
Python
 
Essential language features
Essential language featuresEssential language features
Essential language features
 
Generics Tutorial
Generics TutorialGenerics Tutorial
Generics Tutorial
 
9781439035665 ppt ch03
9781439035665 ppt ch039781439035665 ppt ch03
9781439035665 ppt ch03
 
OOP Poster Presentation
OOP Poster PresentationOOP Poster Presentation
OOP Poster Presentation
 
Implementation
ImplementationImplementation
Implementation
 
Visual studio2012 tipsandtricks
Visual studio2012 tipsandtricksVisual studio2012 tipsandtricks
Visual studio2012 tipsandtricks
 

Viewers also liked

A better way to learn refactoring
A better way to learn refactoringA better way to learn refactoring
A better way to learn refactoring
Rafael Sperling
 
Code Smell Research: History and Future Directions
Code Smell Research: History and Future DirectionsCode Smell Research: History and Future Directions
Code Smell Research: History and Future Directions
Nikolaos Tsantalis
 
Do Code Smell Hamper Novice Programmers?
Do Code Smell Hamper Novice Programmers?Do Code Smell Hamper Novice Programmers?
Do Code Smell Hamper Novice Programmers?
Felienne Hermans
 

Viewers also liked (17)

A better way to learn refactoring
A better way to learn refactoringA better way to learn refactoring
A better way to learn refactoring
 
Code Smells
Code SmellsCode Smells
Code Smells
 
When and Why Your Code Starts to Smell Bad
When and Why Your Code Starts to Smell BadWhen and Why Your Code Starts to Smell Bad
When and Why Your Code Starts to Smell Bad
 
A Catalogue of Code Smell Visualizations
A Catalogue of Code Smell VisualizationsA Catalogue of Code Smell Visualizations
A Catalogue of Code Smell Visualizations
 
Developing design sense of code smells
Developing design sense of code smellsDeveloping design sense of code smells
Developing design sense of code smells
 
Code Smell Research: History and Future Directions
Code Smell Research: History and Future DirectionsCode Smell Research: History and Future Directions
Code Smell Research: History and Future Directions
 
Do Code Smell Hamper Novice Programmers?
Do Code Smell Hamper Novice Programmers?Do Code Smell Hamper Novice Programmers?
Do Code Smell Hamper Novice Programmers?
 
Bad Code Smells
Bad Code SmellsBad Code Smells
Bad Code Smells
 
Code Smells and How to avoid it
Code Smells and How to avoid itCode Smells and How to avoid it
Code Smells and How to avoid it
 
A Textual-based Technique for Smell Detection
A Textual-based Technique for Smell DetectionA Textual-based Technique for Smell Detection
A Textual-based Technique for Smell Detection
 
PhD Symposium 2014
PhD Symposium 2014PhD Symposium 2014
PhD Symposium 2014
 
Code Smell, Software Engineering
Code Smell, Software EngineeringCode Smell, Software Engineering
Code Smell, Software Engineering
 
Detecting Bad Smells in Source Code using Change History Information
Detecting Bad Smells in Source Code using Change History InformationDetecting Bad Smells in Source Code using Change History Information
Detecting Bad Smells in Source Code using Change History Information
 
Does your configuration code smell?
Does your configuration code smell?Does your configuration code smell?
Does your configuration code smell?
 
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorbRuby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
Ruby用の静的コード解析ツールざくっと紹介 by SideCI #omotesandorb
 
Refactoring-ch7 moving feature btw objects
Refactoring-ch7 moving feature btw objectsRefactoring-ch7 moving feature btw objects
Refactoring-ch7 moving feature btw objects
 
Connascence
ConnascenceConnascence
Connascence
 

Similar to Code smells

How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
Mike Harris
 
Agile korea 2013 유석문
Agile korea 2013 유석문Agile korea 2013 유석문
Agile korea 2013 유석문
Sangcheol Hwang
 
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
 
Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
Edorian
 

Similar to Code smells (20)

Refactoring_Rosenheim_2008_Workshop
Refactoring_Rosenheim_2008_WorkshopRefactoring_Rosenheim_2008_Workshop
Refactoring_Rosenheim_2008_Workshop
 
Tech talks#6: Code Refactoring
Tech talks#6: Code RefactoringTech talks#6: Code Refactoring
Tech talks#6: Code Refactoring
 
[Gophercon 2019] Analysing code quality with linters and static analysis
[Gophercon 2019] Analysing code quality with linters and static analysis[Gophercon 2019] Analysing code quality with linters and static analysis
[Gophercon 2019] Analysing code quality with linters and static analysis
 
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
How I Learned to Stop Worrying and Love Legacy Code - Ox:Agile 2018
 
Agile korea 2013 유석문
Agile korea 2013 유석문Agile korea 2013 유석문
Agile korea 2013 유석문
 
Introduction to JavaScript design patterns
Introduction to JavaScript design patternsIntroduction to JavaScript design patterns
Introduction to JavaScript design patterns
 
2011 iska - tim m - domain driven design
2011   iska - tim m - domain driven design2011   iska - tim m - domain driven design
2011 iska - tim m - domain driven design
 
DSL's with Groovy
DSL's with GroovyDSL's with Groovy
DSL's with Groovy
 
Refactoring
RefactoringRefactoring
Refactoring
 
Why Drupal is Rockstar?
Why Drupal is Rockstar?Why Drupal is Rockstar?
Why Drupal is Rockstar?
 
Refactoring, 2nd Edition
Refactoring, 2nd EditionRefactoring, 2nd Edition
Refactoring, 2nd Edition
 
Agile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tddAgile_goa_2013_clean_code_tdd
Agile_goa_2013_clean_code_tdd
 
EKON 23 Code_review_checklist
EKON 23 Code_review_checklistEKON 23 Code_review_checklist
EKON 23 Code_review_checklist
 
Object Oriented Concepts and Principles
Object Oriented Concepts and PrinciplesObject Oriented Concepts and Principles
Object Oriented Concepts and Principles
 
Refactoring merged code - ReSharper meets SemanticMerge
Refactoring merged code - ReSharper meets SemanticMergeRefactoring merged code - ReSharper meets SemanticMerge
Refactoring merged code - ReSharper meets SemanticMerge
 
Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
 
Improving Code Quality Through Effective Review Process
Improving Code Quality Through Effective  Review ProcessImproving Code Quality Through Effective  Review Process
Improving Code Quality Through Effective Review Process
 
API Design
API DesignAPI Design
API Design
 
Code review
Code reviewCode review
Code review
 
Best practices tekx
Best practices tekxBest practices tekx
Best practices tekx
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Code smells

  • 2. O QUE É UM CODE SMELL?
  • 4.
  • 5. •Long Method •Large Class •Primitive Obsession •Long Parameter List •Data Clumps •Switch Statements •Temporary Field •Refused Bequest •Alternative Classes with Different Interfaces •Divergent Change •Shotgun Surgery •Parallel Inheritance Hierarchies •Comments •Duplicate Code •Lazy Class •Data Class •Dead Code •Speculative Generality •Feature Envy •Inappropriate Intimacy •Message Chains •Middle Man •Incomplete Library Class BLOATERS OO ABUSERS CHANGE PREVENTERS DISPENSABLES COUPLERS
  • 6. RefactoringPara todo existe uma receita CODE SMELL que explica como resolver o problema
  • 7.
  • 9. class OrdersReport def initialize(orders, start_date, end_date) @orders = orders @start_date = start_date @end_date = end_date end def total_sales_within_date_range orders_within_range = @orders.select { |order| order.placed_at >= @start_date && order.placed_at <= @end_date } orders_within_range. map(&:amount).inject { |sum, amount| amount + sum } end end class Order < OpenStruct end
  • 10. class OrdersReport def initialize(orders, start_date, end_date) @orders = orders @start_date = start_date @end_date = end_date end def total_sales_within_date_range orders_within_range. map(&:amount).inject { |sum, amount| amount + sum } end private def orders_within_range @orders.select { |order| order.placed_at >= @start_date && order.placed_at <= @end_date } end end class Order < OpenStruct end
  • 11. class OrdersReport def initialize(orders, start_date, end_date) @orders = orders @start_date = start_date @end_date = end_date end def total_sales_within_date_range orders_within_range. map(&:amount).inject { |sum, amount| amount + sum } end private def orders_within_range @orders.select { |order| order.placed_between?(@start_date, @end_date) } end end class Order < OpenStruct def placed_between?(start_date, end_date) placed_at >= start_date && placed_at <= end_date end end
  • 12. class OrdersReport def initialize(orders, date_range) @orders = orders @date_range = date_range end def total_sales_within_date_range orders_within_range. map(&:amount).inject { |sum, amount| amount + sum } end private def orders_within_range @orders.select { |order| order.placed_between?(@date_range) } end end class DateRange < Struct.new(:start_date, :end_date) end class Order < OpenStruct def placed_between?(date_range) placed_at >= date_range.start_date && placed_at <= date_range.end_date end end
  • 13. class OrdersReport def initialize(orders, date_range) @orders = orders @date_range = date_range end def total_sales_within_date_range orders_within_range. map(&:amount).inject { |sum, amount| amount + sum } end private def orders_within_range @orders.select { |order| order.placed_between?(@date_range) } end end class DateRange < Struct.new(:start_date, :end_date) def include?(date) (start_date..end_date).cover?(date) end end class Order < OpenStruct def placed_between?(date_range) date_range.include?(placed_at) end end
  • 14.
  • 17.
  • 19. 99 bottles of beer on the wall, 99 bottles of beer. Take one down and pass it around, 98 bottles of beer on the wall. 98 bottles of beer on the wall, 98 bottles of beer. Take one down and pass it around, 97 bottles of beer on the wall. 97 bottles of beer on the wall, 97 bottles of beer. Take one down and pass it around, 96 bottles of beer on the wall. … 2 bottles of beer on the wall, 2 bottles of beer. Take one down and pass it around, 1 bottle of beer on the wall. 1 bottle of beer on the wall, 1 bottle of beer. Take one down and pass it around, no more bottles of beer on the wall. No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.
  • 20.
  • 21. A satisfactory modular decomposition technique must satisfy one more requirement: It should yield modules that are both open and closed. • A module will be said to be open if it is available for extension. For example, it should be possible to add fields to the data structures it contains, or new elements to the set of functions it performs. • A module will be said to be closed if is available for use by other modules. This assumes that the module has been given a well-defined, stable description (the interface in the sense of information hiding). In the case of a programming language module, a closed module is one that may be compiled and stored in a library, for others to use. In the case of a design or specification module, closing a module simply means having it approved by management, adding it to the project's official repository of accepted software items (often called the project baseline), and publishing its interface for the benefit of other module designers. Robert C. Martin SOLID
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.