SlideShare a Scribd company logo
1 of 59
Follow me at twitter.com/ardalis
Refactoring Applications
using SOLID Principles
Steve Smith
Telerik
ardalis.com @ardalis
Follow me at twitter.com/ardalis
More on this topic
Coming Soon: Refactoring Fundamentals
Follow me at twitter.com/ardalis




Follow me at twitter.com/ardalis
Preventive Maintenance
• Refactoring
– Eliminate Duplication
– Simplify Design
• Automated Tests
– Verify correctness
– Avoid regressions
– Increase Confidence
Follow me at twitter.com/ardalis
Refactoring Process
• Verify existing behavior
• Write Characterization Tests if none exist
– Find test points
– Break dependencies
• Apply Refactoring
• Confirm existing behavior is preserved
Follow me at twitter.com/ardalis
Characterization Tests
Process
1. Write a test you know will fail
2. Use the output of the failing test to
determine the existing behavior to assert
3. Update the test with the new
value/behavior
4. Run the test again – it should pass
S O L I DPrinciples
http://flickr.com/photos/kevinkemmerer/2772526725
Follow me at twitter.com/ardalis
Principles of OO Design
0. Don’t Repeat Yourself (DRY)
1. Single Responsibility
2. Open/Closed
3. Liskov Substitution
4. Interface Segregation
5. Dependency Inversion
Follow me at twitter.com/ardalis
Don’t Repeat
Repeat Yourself
• Duplication in logic calls for abstraction
• Duplication in process calls for
automation
Follow me at twitter.com/ardalis
Common Refactorings
• Replace Magic Number/String
• Parameterize Method
• Pull Up Field
• Pull Up Method
• Replace Conditional With Polymorphism
• Introduce Method
Follow me at twitter.com/ardalis
Role Checks
if(user.IsInRole(“Admins”)
{
// allow access to resource
}
// favor privileges over role checks
// ardalis.com/Favor-Privileges-over-Role-Checks
var priv = new ContentPrivilege(user, article);
if(priv.CanEdit())
{
// allow access
}
Follow me at twitter.com/ardalis
Single Responsibility Principle
The Single Responsibility Principle states that every object
should have a single responsibility, and that
responsibility should be entirely encapsulated by the
class.
Wikipedia
There should never be more than one reason for a class to
change.
Robert C. “Uncle Bob” Martin
Follow me at twitter.com/ardalis
Example Responsibilities
• Persistence
• Validation
• Notification
• Error Handling
• Logging
• Class Selection / Construction
• Formatting
• Parsing
• Mapping
Follow me at twitter.com/ardalis
Dependency and Coupling
• Excessive coupling makes changing
legacy software difficult
• Breaking apart responsibilities and
dependencies is a large part of working
with existing code
Follow me at twitter.com/ardalis
Common Refactorings
• Extract Class
• Move Method
Follow me at twitter.com/ardalis
Heuristics and Code Smells
• Visual Studio Metrics
Follow me at twitter.com/ardalis
Code Smell: Regions
More on Regions: http://ardalis.com/regional-differences
Follow me at twitter.com/ardalis
Open / Closed Principle
The Open / Closed Principle states that software entities
(classes, modules, functions, etc.) should be open for
extension, but closed for modification.
Wikipedia
Follow me at twitter.com/ardalis
Open / Closed Principle
Open to Extension
New behavior can be added in the future
Closed to Modification
Changes to source or binary code are not required
Dr. Bertrand Meyer originated the OCP term in his 1988
book, Object Oriented Software Construction
Follow me at twitter.com/ardalis
Common Refactorings
• Extract Interface / Apply Strategy Pattern
• Parameterize Method
• Form Template Method
Follow me at twitter.com/ardalis
OCP Fail
Follow me at twitter.com/ardalis
OCP OK
Follow me at twitter.com/ardalis
OCP Fail
public bool IsSpecialCustomer(Customer c)
{
if(c.Country == “US” && c.Balance < 50) return false;
if(c.Country == “DE” && c.Balance < 25) return false;
if(c.Country == “UK” && c.Balance < 35) return false;
if(c.Country == “FR” && c.Balance < 27) return false;
if(c.Country == “BG” && c.Balance < 29) return false;
if(c.Age < 18 || c.Age > 65) return false;
if(c.Income < 50000 && c.Age < 30) return false;
return true;
}
Follow me at twitter.com/ardalis
OCP OK
private IEnumerable<ICustomerRule> _rules;
public bool IsSpecialCustomer(Customer c)
{
foreach(var rule in _rules)
{
if(rule.Evaluate(c) == false) return false;
}
return true;
}
Follow me at twitter.com/ardalis
Liskov Substitution Principle
The Liskov Substitution Principle states that
Subtypes must be substitutable for their
base types.
Agile Principles, Patterns, and Practices in
C#
Named for Barbara Liskov, who first
described the principle in 1988.
Follow me at twitter.com/ardalis
Common Refactorings
• Collapse Hierarchy
• Pull Up / Push Down Field
• Pull Up / Push Down Method
Follow me at twitter.com/ardalis
Liskov Substitution Fail
foreach(var employee in employees)
{
if(employee is Manager)
{
Helpers.PrintManager(employee as Manager);
break;
}
Helpers.PrintEmployee(employee);
}
Follow me at twitter.com/ardalis
Liskov Substitution OK
foreach(var employee in employees)
{
employee.Print();
// or
Helpers.PrintEmployee(employee);
}
Follow me at twitter.com/ardalis
Interface Segregation Principle
The Interface Segregation Principle states that
Clients should not be forced to depend on
methods they do not use.
Agile Principles, Patterns, and Practices in C#
Corollary:
Prefer small, cohesive interfaces to “fat” interfaces
Follow me at twitter.com/ardalis
Common Refactorings
• Extract Interface
Follow me at twitter.com/ardalis
ISP Fail (sometimes)
public IRepository<T>
{
T GetById(int id);
IEnumerable<T> List();
void Create(T item);
void Update(T item);
void Delete(T item);
}
Follow me at twitter.com/ardalis
ISP OK (for CQRS for example)
public IRepository<T> : IReadRepository<T>,
IWriteRepository<T>
{ }
public IReadRepository<T>
{
T GetById(int id);
IEnumerable<T> List();
}
public IWriteRepository<T>
void Create(T item);
void Update(T item);
void Delete(T item);
}
Follow me at twitter.com/ardalis
Dependency Inversion Principle
High-level modules should not depend on low-level
modules. Both should depend on abstractions.
Abstractions should not depend on details. Details
should depend on abstractions.
Agile Principles, Patterns, and Practices in C#
Follow me at twitter.com/ardalis
Dependency Inversion Principle
• Depend on Abstractions
– Interfaces, not concrete types
• Inject Dependencies into Classes
• Structure Solution so Dependencies Flow
Toward Core
– Onion Architecture
Follow me at twitter.com/ardalis
Application Layers
Follow me at twitter.com/ardalis






User Interface
Database
Compile Time
Runtime
Follow me at twitter.com/ardalis




User Interface
Database
Compile Time
Runtime
Helper Class
Follow me at twitter.com/ardalis






User Interface
Database
Compile Time
Runtime
Core
IFooRepository
Infrastructure
SqlFooRepository
Follow me at twitter.com/ardalis
DIP “Onion” Architecture
Follow me at twitter.com/ardalis
Common Dependencies
• Framework
• Third Party Libraries
• Database
• File System
• Email
• Web Services
• System Resources (Clock)
• Configuration
• The new Keyword
• Static methods
• Thread.Sleep
• Random
See also responsibilities:
• Persistence
• Validation
• Notification
• Error Handling
• Logging
• Class Selection /
Construction
• Formatting
• Parsing
• Mapping
Follow me at twitter.com/ardalis
Common Refactorings
• Extract Class
• Extract Interface / Apply Strategy Pattern
• Extract Method
• Introduce Service Locator / Container
Follow me at twitter.com/ardalis
DIP Fail
Follow me at twitter.com/ardalis
Some Improvement (Façade)
Follow me at twitter.com/ardalis
DIP OK (Strategy)
Follow me at twitter.com/ardalis
DIP OK (Strategy)
Follow me at twitter.com/ardalis
Summary
• Maintain / Improve Application Code
• Follow DRY/SOLID Principles
• Use Characterization Tests to “fix”
behavior
• Apply Common Refactorings
• Re-run Tests After (and during)
Refactorings
Follow me at twitter.com/ardalis






Follow me at twitter.com/ardalis





Follow me at twitter.com/ardalis
Thank You!
Find Me Online:
Blog: http://ardalis.com
Twitter: @ardalis
http://facebook.com/StevenAndrewSmith
Follow me at twitter.com/ardalis

More Related Content

Similar to Refactoring with SOLID Principles (FalafelCon 2013)

Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Steven Smith
 
Principled And Clean Coding
Principled And Clean CodingPrincipled And Clean Coding
Principled And Clean CodingMetin Ogurlu
 
CodeIgniter for Startups, cicon2010
CodeIgniter for Startups, cicon2010CodeIgniter for Startups, cicon2010
CodeIgniter for Startups, cicon2010Joel Gascoigne
 
I gotta dependency on dependency injection
I gotta dependency on dependency injectionI gotta dependency on dependency injection
I gotta dependency on dependency injectionmhenroid
 
Object-oriented design principles
Object-oriented design principlesObject-oriented design principles
Object-oriented design principlesXiaoyan Chen
 
Clean code presentation
Clean code presentationClean code presentation
Clean code presentationBhavin Gandhi
 
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdf
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdfSlides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdf
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdfChristineCheong5
 
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Steven Smith
 
Rethinking system design
Rethinking system designRethinking system design
Rethinking system designBryan Ollendyke
 
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2Elizabeth Steiner
 
Apache Spark Model Deployment
Apache Spark Model Deployment Apache Spark Model Deployment
Apache Spark Model Deployment Databricks
 
Software design with Domain-driven design
Software design with Domain-driven design Software design with Domain-driven design
Software design with Domain-driven design Allan Mangune
 
Object Oriented Programming in Swift Ch0 - Encapsulation
Object Oriented Programming in Swift Ch0 - EncapsulationObject Oriented Programming in Swift Ch0 - Encapsulation
Object Oriented Programming in Swift Ch0 - EncapsulationChihyang Li
 
ELMSLN: Rethinking System Architecture
ELMSLN: Rethinking System ArchitectureELMSLN: Rethinking System Architecture
ELMSLN: Rethinking System ArchitectureBryan Ollendyke
 

Similar to Refactoring with SOLID Principles (FalafelCon 2013) (20)

Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing Software
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016
 
Principled And Clean Coding
Principled And Clean CodingPrincipled And Clean Coding
Principled And Clean Coding
 
CodeIgniter for Startups, cicon2010
CodeIgniter for Startups, cicon2010CodeIgniter for Startups, cicon2010
CodeIgniter for Startups, cicon2010
 
I gotta dependency on dependency injection
I gotta dependency on dependency injectionI gotta dependency on dependency injection
I gotta dependency on dependency injection
 
Object-oriented design principles
Object-oriented design principlesObject-oriented design principles
Object-oriented design principles
 
Clean code presentation
Clean code presentationClean code presentation
Clean code presentation
 
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdf
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdfSlides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdf
Slides-Introduction-to-System-Dynamics-Modeling-October-20-2021.pdf
 
Mvc
MvcMvc
Mvc
 
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
 
Rethinking system design
Rethinking system designRethinking system design
Rethinking system design
 
31 days Refactoring
31 days Refactoring31 days Refactoring
31 days Refactoring
 
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2
Model-Based Systems Engineering Tool How To Use Innoslate Pt. 2
 
Apache Spark Model Deployment
Apache Spark Model Deployment Apache Spark Model Deployment
Apache Spark Model Deployment
 
Software design with Domain-driven design
Software design with Domain-driven design Software design with Domain-driven design
Software design with Domain-driven design
 
Object Oriented Programming in Swift Ch0 - Encapsulation
Object Oriented Programming in Swift Ch0 - EncapsulationObject Oriented Programming in Swift Ch0 - Encapsulation
Object Oriented Programming in Swift Ch0 - Encapsulation
 
ELMSLN: Rethinking System Architecture
ELMSLN: Rethinking System ArchitectureELMSLN: Rethinking System Architecture
ELMSLN: Rethinking System Architecture
 

More from Steven Smith

Clean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisClean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisSteven Smith
 
Finding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsFinding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsSteven Smith
 
Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Steven Smith
 
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Steven Smith
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashSteven Smith
 
Most Useful Design Patterns
Most Useful Design PatternsMost Useful Design Patterns
Most Useful Design PatternsSteven Smith
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Steven Smith
 
Decoupling with Domain Events
Decoupling with Domain EventsDecoupling with Domain Events
Decoupling with Domain EventsSteven Smith
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingSteven Smith
 
A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5Steven Smith
 
My Iraq Experience
My Iraq ExperienceMy Iraq Experience
My Iraq ExperienceSteven Smith
 
Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Steven Smith
 
Domain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCDomain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCSteven Smith
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingSteven Smith
 
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Steven Smith
 
Common asp.net design patterns aspconf2012
Common asp.net design patterns aspconf2012Common asp.net design patterns aspconf2012
Common asp.net design patterns aspconf2012Steven Smith
 
Common design patterns (migang 16 May 2012)
Common design patterns (migang 16 May 2012)Common design patterns (migang 16 May 2012)
Common design patterns (migang 16 May 2012)Steven Smith
 
Introducing Pair Programming
Introducing Pair ProgrammingIntroducing Pair Programming
Introducing Pair ProgrammingSteven Smith
 
Cinci ug-january2011-anti-patterns
Cinci ug-january2011-anti-patternsCinci ug-january2011-anti-patterns
Cinci ug-january2011-anti-patternsSteven Smith
 

More from Steven Smith (20)

Clean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisClean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by Ardalis
 
Finding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsFinding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design Patterns
 
Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018
 
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemash
 
Most Useful Design Patterns
Most Useful Design PatternsMost Useful Design Patterns
Most Useful Design Patterns
 
Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0Introducing ASP.NET Core 2.0
Introducing ASP.NET Core 2.0
 
Decoupling with Domain Events
Decoupling with Domain EventsDecoupling with Domain Events
Decoupling with Domain Events
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5
 
Domain events
Domain eventsDomain events
Domain events
 
My Iraq Experience
My Iraq ExperienceMy Iraq Experience
My Iraq Experience
 
Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?
 
Domain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCDomain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVC
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013Common ASP.NET Design Patterns - Telerik India DevCon 2013
Common ASP.NET Design Patterns - Telerik India DevCon 2013
 
Common asp.net design patterns aspconf2012
Common asp.net design patterns aspconf2012Common asp.net design patterns aspconf2012
Common asp.net design patterns aspconf2012
 
Common design patterns (migang 16 May 2012)
Common design patterns (migang 16 May 2012)Common design patterns (migang 16 May 2012)
Common design patterns (migang 16 May 2012)
 
Introducing Pair Programming
Introducing Pair ProgrammingIntroducing Pair Programming
Introducing Pair Programming
 
Cinci ug-january2011-anti-patterns
Cinci ug-january2011-anti-patternsCinci ug-january2011-anti-patterns
Cinci ug-january2011-anti-patterns
 

Recently uploaded

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 

Recently uploaded (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 

Refactoring with SOLID Principles (FalafelCon 2013)

  • 1. Follow me at twitter.com/ardalis Refactoring Applications using SOLID Principles Steve Smith Telerik ardalis.com @ardalis
  • 2. Follow me at twitter.com/ardalis More on this topic Coming Soon: Refactoring Fundamentals
  • 3. Follow me at twitter.com/ardalis    
  • 4.
  • 5. Follow me at twitter.com/ardalis Preventive Maintenance • Refactoring – Eliminate Duplication – Simplify Design • Automated Tests – Verify correctness – Avoid regressions – Increase Confidence
  • 6. Follow me at twitter.com/ardalis Refactoring Process • Verify existing behavior • Write Characterization Tests if none exist – Find test points – Break dependencies • Apply Refactoring • Confirm existing behavior is preserved
  • 7. Follow me at twitter.com/ardalis Characterization Tests Process 1. Write a test you know will fail 2. Use the output of the failing test to determine the existing behavior to assert 3. Update the test with the new value/behavior 4. Run the test again – it should pass
  • 8.
  • 9.
  • 10. S O L I DPrinciples http://flickr.com/photos/kevinkemmerer/2772526725
  • 11. Follow me at twitter.com/ardalis Principles of OO Design 0. Don’t Repeat Yourself (DRY) 1. Single Responsibility 2. Open/Closed 3. Liskov Substitution 4. Interface Segregation 5. Dependency Inversion
  • 12.
  • 13. Follow me at twitter.com/ardalis Don’t Repeat Repeat Yourself • Duplication in logic calls for abstraction • Duplication in process calls for automation
  • 14. Follow me at twitter.com/ardalis Common Refactorings • Replace Magic Number/String • Parameterize Method • Pull Up Field • Pull Up Method • Replace Conditional With Polymorphism • Introduce Method
  • 15. Follow me at twitter.com/ardalis Role Checks if(user.IsInRole(“Admins”) { // allow access to resource } // favor privileges over role checks // ardalis.com/Favor-Privileges-over-Role-Checks var priv = new ContentPrivilege(user, article); if(priv.CanEdit()) { // allow access }
  • 16.
  • 17. Follow me at twitter.com/ardalis Single Responsibility Principle The Single Responsibility Principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. Wikipedia There should never be more than one reason for a class to change. Robert C. “Uncle Bob” Martin
  • 18. Follow me at twitter.com/ardalis Example Responsibilities • Persistence • Validation • Notification • Error Handling • Logging • Class Selection / Construction • Formatting • Parsing • Mapping
  • 19. Follow me at twitter.com/ardalis Dependency and Coupling • Excessive coupling makes changing legacy software difficult • Breaking apart responsibilities and dependencies is a large part of working with existing code
  • 20. Follow me at twitter.com/ardalis Common Refactorings • Extract Class • Move Method
  • 21. Follow me at twitter.com/ardalis Heuristics and Code Smells • Visual Studio Metrics
  • 22. Follow me at twitter.com/ardalis Code Smell: Regions More on Regions: http://ardalis.com/regional-differences
  • 23.
  • 24. Follow me at twitter.com/ardalis Open / Closed Principle The Open / Closed Principle states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Wikipedia
  • 25. Follow me at twitter.com/ardalis Open / Closed Principle Open to Extension New behavior can be added in the future Closed to Modification Changes to source or binary code are not required Dr. Bertrand Meyer originated the OCP term in his 1988 book, Object Oriented Software Construction
  • 26. Follow me at twitter.com/ardalis Common Refactorings • Extract Interface / Apply Strategy Pattern • Parameterize Method • Form Template Method
  • 27. Follow me at twitter.com/ardalis OCP Fail
  • 28. Follow me at twitter.com/ardalis OCP OK
  • 29. Follow me at twitter.com/ardalis OCP Fail public bool IsSpecialCustomer(Customer c) { if(c.Country == “US” && c.Balance < 50) return false; if(c.Country == “DE” && c.Balance < 25) return false; if(c.Country == “UK” && c.Balance < 35) return false; if(c.Country == “FR” && c.Balance < 27) return false; if(c.Country == “BG” && c.Balance < 29) return false; if(c.Age < 18 || c.Age > 65) return false; if(c.Income < 50000 && c.Age < 30) return false; return true; }
  • 30. Follow me at twitter.com/ardalis OCP OK private IEnumerable<ICustomerRule> _rules; public bool IsSpecialCustomer(Customer c) { foreach(var rule in _rules) { if(rule.Evaluate(c) == false) return false; } return true; }
  • 31.
  • 32. Follow me at twitter.com/ardalis Liskov Substitution Principle The Liskov Substitution Principle states that Subtypes must be substitutable for their base types. Agile Principles, Patterns, and Practices in C# Named for Barbara Liskov, who first described the principle in 1988.
  • 33. Follow me at twitter.com/ardalis Common Refactorings • Collapse Hierarchy • Pull Up / Push Down Field • Pull Up / Push Down Method
  • 34. Follow me at twitter.com/ardalis Liskov Substitution Fail foreach(var employee in employees) { if(employee is Manager) { Helpers.PrintManager(employee as Manager); break; } Helpers.PrintEmployee(employee); }
  • 35. Follow me at twitter.com/ardalis Liskov Substitution OK foreach(var employee in employees) { employee.Print(); // or Helpers.PrintEmployee(employee); }
  • 36.
  • 37. Follow me at twitter.com/ardalis Interface Segregation Principle The Interface Segregation Principle states that Clients should not be forced to depend on methods they do not use. Agile Principles, Patterns, and Practices in C# Corollary: Prefer small, cohesive interfaces to “fat” interfaces
  • 38. Follow me at twitter.com/ardalis Common Refactorings • Extract Interface
  • 39. Follow me at twitter.com/ardalis ISP Fail (sometimes) public IRepository<T> { T GetById(int id); IEnumerable<T> List(); void Create(T item); void Update(T item); void Delete(T item); }
  • 40. Follow me at twitter.com/ardalis ISP OK (for CQRS for example) public IRepository<T> : IReadRepository<T>, IWriteRepository<T> { } public IReadRepository<T> { T GetById(int id); IEnumerable<T> List(); } public IWriteRepository<T> void Create(T item); void Update(T item); void Delete(T item); }
  • 41.
  • 42. Follow me at twitter.com/ardalis Dependency Inversion Principle High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. Agile Principles, Patterns, and Practices in C#
  • 43. Follow me at twitter.com/ardalis Dependency Inversion Principle • Depend on Abstractions – Interfaces, not concrete types • Inject Dependencies into Classes • Structure Solution so Dependencies Flow Toward Core – Onion Architecture
  • 44. Follow me at twitter.com/ardalis Application Layers
  • 45. Follow me at twitter.com/ardalis       User Interface Database Compile Time Runtime
  • 46. Follow me at twitter.com/ardalis     User Interface Database Compile Time Runtime Helper Class
  • 47. Follow me at twitter.com/ardalis       User Interface Database Compile Time Runtime Core IFooRepository Infrastructure SqlFooRepository
  • 48. Follow me at twitter.com/ardalis DIP “Onion” Architecture
  • 49. Follow me at twitter.com/ardalis Common Dependencies • Framework • Third Party Libraries • Database • File System • Email • Web Services • System Resources (Clock) • Configuration • The new Keyword • Static methods • Thread.Sleep • Random See also responsibilities: • Persistence • Validation • Notification • Error Handling • Logging • Class Selection / Construction • Formatting • Parsing • Mapping
  • 50. Follow me at twitter.com/ardalis Common Refactorings • Extract Class • Extract Interface / Apply Strategy Pattern • Extract Method • Introduce Service Locator / Container
  • 51. Follow me at twitter.com/ardalis DIP Fail
  • 52. Follow me at twitter.com/ardalis Some Improvement (Façade)
  • 53. Follow me at twitter.com/ardalis DIP OK (Strategy)
  • 54. Follow me at twitter.com/ardalis DIP OK (Strategy)
  • 55. Follow me at twitter.com/ardalis Summary • Maintain / Improve Application Code • Follow DRY/SOLID Principles • Use Characterization Tests to “fix” behavior • Apply Common Refactorings • Re-run Tests After (and during) Refactorings
  • 56. Follow me at twitter.com/ardalis      
  • 57. Follow me at twitter.com/ardalis     
  • 58. Follow me at twitter.com/ardalis Thank You! Find Me Online: Blog: http://ardalis.com Twitter: @ardalis http://facebook.com/StevenAndrewSmith
  • 59. Follow me at twitter.com/ardalis

Editor's Notes

  1. Note that characterization tests, though they should be automated, are often not what we would think of as unit tests, or perhaps even integration tests. For instance, you could dump a log file showing the relevant state of the application, and then use that as the basis for your characterization test by comparing against it after your changes.
  2. Avoid creating a big ball of mud system, where tracing through your code and its dependencies is like trying to unwind a tangled mess of spaghetti.
  3. A very common source of repetition of code is role checks. These often describe different scenarios in different circumstances. For instance, maybe administrators can do anything, but managers can access resources within their division, etc. Encapsulating the logic of CanView, CanCreate, CanEdit, etc. in privilege objects makes these rules explicit, easier to test, and gives them a single location to live in the application.
  4. Visual Studio can quickly analyze a project and show statistics for the classes and methods in the project. The maintainability index, cyclomatic complexity, and lines of code are all great metrics to pay attention to. The ideal maintainability index is 100, but don’t expect to hit that with any code that’s doing real work. However, you should certainly able to keep it above 50.
  5. I’m not a fan of regions. They mainly exist because at one time they were a reasonable means of hiding generated code, before we had support for partial classes and other language features to deal with this. The worst offense with regions is when they’re used within a method, like this:(click)They’re also bad when used at the class level for “standard” formatting of code, making it impossible to actually see what the code does, like this:(click)Can someone tell me what this class does?(click)I have a whole article devoted to why using regions is a bad habit, anti-pattern, code smell, whatever you prefer. It includes some survey results on the most common ways people use them as well. (click)
  6. What happens when we need to add another country?What happens when we must add another rule?How can we refactor this so this method no longer needs to change?
  7. Define a type to describe a rule. Move each rule into its own type. Create a collection of rules to apply and apply them.Pass the set of rules into the IsSpecialCustomer() method’s class (or even the method itself).
  8. Any time you find that you need to check the type of an object within a polymorphic block of code (such as a foreach), this is a sign that you are breaking LSP.
  9. This is anextemely common example of the Repository design pattern. In fact, I use this exact pattern in quite a few production applications today. There’s nothing inherently wrong with this implementation on its own. However, sometimes it does violate ISP if you need to separate Commands from Queries
  10. You can create small interfaces and compose the larger interfaces from the smaller ones if you control all of the code and you can’t simply do away with the larger interfaces. In this case, the separation of interfaces would allow us to do something like implement caching only on the read operations, and implement delayed writes using some kind of queue or message bus for the write operations.
  11. Extract interfaceImplement interface with tightly coupled original code
  12. http://en.wikipedia.org/wiki/Template_method_pattern