SlideShare a Scribd company logo
1 of 31
Strategy Pattern
ThePicture.getInstance(new TakeStrategy());
image
What is it?
“Define a family of algorithms, encapsulate each one, and
make them interchangeable. Strategy lets the algorithm
vary independently from clients that use it.” Gang of Four
image
Why would I use it?
Strategy lets the algorithm vary independently from clients that use it
Strategy pattern allows you to prefer composition over inheritance
Adhere’s to the Open/Closed principle of SOLID
Helps manage the complexity of having numerous variations of an
algorithm
Replacing conditional
logic with the strategy
pattern
if(designPattern) {
profit();
}
image
Walkthrough
Conditional logic in a variant controls which of several
variants of a calculation are executed.
Create a strategy for each variant and make the method
delegate the calculation to a Strategy instance.
public double capital() {
if (expiry == null && maturity != null)
return commitment * duration() * riskFactor();
if (expiry != null && maturity == null) {
if (getUnusedPercentage() != 1) {
return commitment * getUnusedPercentage()
* duration() * riskFactor();
} else {
return (outstandingRiskAmount() * duration() * riskFactor())
+ unusedRiskAmount() * duration() * unusedRiskFactor();
}
}
return 0.0d;
}
public double capital() {
return capitalStrategy.capital(this);
}
public double capital(Loan loan) {
return loan.getCommitment()
* duration(loan)
* riskFactorFor(loan);
}
Loan
double capital() : double
Loan
double capital() : double
CapitalStrategy
capital(loan : Loan) : double
CapitalStrategyAdvisedLine
capital(loan : Loan) : double
CapitalStrategyRevolver
capital(loan : Loan) : double
CapitalStrategyTermLoan
capital(loan : Loan) : double
1
Create a Concrete Strategy
public class CapitalStrategy {
}
Delegate to your Concrete
Strategy
public double capital() {
return new CapitalStrategy().capital(this);
}
public double capital() {
return new CapitalStrategy().capital(expiry, maturity, commitment, duration(), riskFactor()...);
}
Pass the context as parameter
Pass the necessary data parameters
Pass the context as parameter
- Making context methods visible to obtain
information, breaking ‘information hiding’
+ When your class gets new public methods they’re
instantly available
Pass the necessary data
parameters
- All data will be passed to all strategies regardless if
it needs that data
+ Involves the least coupling between the context and
the strategy
Pass the context as
parameter
public class CapitalStrategy {
public double capital(Loan loan) {
if (loan.getExpiry() == null && loan.getMaturity() != null) {
return loan.getCommitment() * loan.duration() * riskFactorFor(loan);
}
if (loan.getExpiry() != null && loan.getMaturity() == null) {
if (loan.getUnusedPercentage() != 1) {
return loan.getCommitment() * loan.getUnusedPercentage()
* loan.duration() * riskFactorFor(loan);
} else {
return (loan.outstandingRiskAmount()
* loan.duration() * riskFactorFor(loan))
+ loan.unusedRiskAmount()
* loan.duration() * unusedRiskFactorFor(loan);
}
}
return 0d;
}
}
private double riskFactorFor(Loan loan) {
return 0;
}
private double unusedRiskFactorFor(Loan loan) {
return 0;
}
Pass the context as
parameterpublic class Loan {
….
public double capital() {
return new CapitalStrategy().capital(this);
}
double duration() {
return 0d;
}
int getUnusedPercentage() {
return new Random().nextInt(1);
}
double outstandingRiskAmount() {
return 0d;
}
double unusedRiskAmount() {
return 0d;
}
Date getExpiry() {
return expiry;
}
Date getMaturity() {
return maturity;
}
double getCommitment() {
return commitment;
}
}
Move functionality related to capital calc
public class CapitalStrategy {
public double capital(Loan loan) {
if (loan.getExpiry() == null && loan.getMaturity() != null) {
return loan.getCommitment() * duration() * riskFactorFor(loan);
}
if (loan.getExpiry() != null && loan.getMaturity() == null) {
if (getUnusedPercentage() != 1) {
return loan.getCommitment() * getUnusedPercentage()
* duration() * riskFactorFor(loan);
} else {
return (outstandingRiskAmount()
* duration() * riskFactorFor(loan))
+ unusedRiskAmount()
* duration() * unusedRiskFactorFor(loan);
}
}
return 0d;
}
...
Extract Field
public class Loan {
private final Date expiry;
private final Date maturity;
private final double commitment;
private final CapitalStrategy strategy;
public Loan(Date expiry, Date maturity, double commitment) {
this.expiry = expiry;
this.maturity = maturity;
this.commitment = commitment;
this.strategy = new CapitalStrategy();
}
public double capital() {
return strategy.capital(this);
}
...
...
Date getExpiry() {
return expiry;
}
Date getMaturity() {
return maturity;
}
double getCommitment() {
return commitment;
}
}
Extract Parameter
public static Loan newTermLoad(Date expiry, Date maturity, double commitment) {
return new Loan(expiry, maturity, commitment, new CapitalStrategy());
}
public static Loan newRevolver(Date expiry, Date maturity, double commitment) {
return new Loan(expiry, maturity, commitment, new CapitalStrategy());
}
public Loan(Date expiry, Date maturity, double commitment, CapitalStrategy capitalStrategy) {
this.expiry = expiry;
this.maturity = maturity;
this.commitment = commitment;
this.strategy = capitalStrategy;
}
Replace conditional with Polymorphism
public class CapitalStrategyTermLoan extends CapitalStrategy {
public double capital(Loan loan) {
return loan.getCommitment() * duration() * riskFactorFor(loan);
}
@Override
protected double duration() {
return 0d; // specific calculation for term loans
}
}
public static Loan newTermLoad(Date expiry, Date maturity, double commitment) {
return new Loan(expiry, maturity, commitment, new CapitalStrategyTermLoan());
}
Replace conditional with Polymorphism
public static Loan newTermLoad(Date expiry, Date maturity, double commitment) {
return new Loan(expiry, maturity, commitment, new CapitalStrategyTermLoan());
}
public static Loan newRevolver(Date expiry, Date maturity, double commitment) {
return new Loan(expiry, maturity, commitment, new CapitalStrategyRevolver());
}
public static Loan newAdvisedLine(Date expiry, Date maturity, double commitment, int riskRating) {
if(riskRating > 3) return null;
return new Loan(expiry, maturity, commitment, new CapitalStrategyAdvisedLine());
}
CapitalStrategy changes
public abstract class CapitalStrategy {
public abstract double capital(Loan loan);
protected double duration() {
return 0d; // shared implementation
}
protected double riskFactorFor(Loan loan) {
return 0d; // shared implementation
}
}
image
Benefits
+ Clarifies algorithms by decreasing or moving conditional
logic
+ Simplifies a class by moving variations of an algorithm
to a hierarchy
+ Enables one algorithm to be swapped for another at
runtime
Liabilities
- Complicates a design when simpler refactorings like
compose method are available
- Complicates how an algorithm obtains or receives data
from their context class
image
Alternatives
Smaller changes
- Compose Method
- Decompose conditional
More suited changes
- Move embellishment to decorator
- Replace conditional with polymorphism
see: Refactoring to Patterns - Joshua Kerievsky
image
Refactoring ‘towards’ a
pattern- Refactor to, towards or away
- Some patterns are all or nothing
- Aim is always for a better design
- Evaluate if the design has improved
- Pools of Insight
http://www.industriallogic.com/papers/khdraft.pdf
Further Reading
Refactoring - Martin Fowler
Refactoring to Patterns - Joshua Kerievsky
Head First Design Patterns - Elisabeth Freeman
Design Patterns - Gof
https://www.goodreads.com/genres/novoda-new-starts-
reading
throw new SlideIndexOutOfBoundsException();
@blundell_apps
+paulblundell
blundell

More Related Content

Similar to Java Patterns - Strategy

Storage Plug-ins
Storage Plug-ins Storage Plug-ins
Storage Plug-ins
buildacloud
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven Development
AgileOnTheBeach
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
Kaniska Mandal
 

Similar to Java Patterns - Strategy (20)

Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
Dependency Injection for Android @ Ciklum speakers corner Kiev 29. May 2014
 
Storage Plug-ins
Storage Plug-ins Storage Plug-ins
Storage Plug-ins
 
CloudStack Meetup Santa Clara
CloudStack Meetup Santa Clara CloudStack Meetup Santa Clara
CloudStack Meetup Santa Clara
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Sustaining Test-Driven Development
Sustaining Test-Driven DevelopmentSustaining Test-Driven Development
Sustaining Test-Driven Development
 
JavaScript Refactoring
JavaScript RefactoringJavaScript Refactoring
JavaScript Refactoring
 
Java beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designJava beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application design
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Simple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docx
Simple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docxSimple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docx
Simple Commsion Calculationbuild.xmlBuilds, tests, and runs t.docx
 
MVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) DetailsMVM - It's all in the (Implementation) Details
MVM - It's all in the (Implementation) Details
 
Morgagebuildclasses.netbeans_automatic_buildMorgagebui.docx
Morgagebuildclasses.netbeans_automatic_buildMorgagebui.docxMorgagebuildclasses.netbeans_automatic_buildMorgagebui.docx
Morgagebuildclasses.netbeans_automatic_buildMorgagebui.docx
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
Data binding в массы!
Data binding в массы!Data binding в массы!
Data binding в массы!
 
Oleksandr Tolstykh
Oleksandr TolstykhOleksandr Tolstykh
Oleksandr Tolstykh
 
How much do we know about Object-Oriented Programming?
How much do we know about Object-Oriented Programming?How much do we know about Object-Oriented Programming?
How much do we know about Object-Oriented Programming?
 
Refactoring legacy code: step-by-step examples
Refactoring legacy code: step-by-step examplesRefactoring legacy code: step-by-step examples
Refactoring legacy code: step-by-step examples
 
Android - Api & Debugging in Android
Android - Api & Debugging in AndroidAndroid - Api & Debugging in Android
Android - Api & Debugging in Android
 
Diving in the Flex Data Binding Waters
Diving in the Flex Data Binding WatersDiving in the Flex Data Binding Waters
Diving in the Flex Data Binding Waters
 

More from Paul Blundell

More from Paul Blundell (14)

In 10 mins a software crafting journey
In 10 mins a software crafting journeyIn 10 mins a software crafting journey
In 10 mins a software crafting journey
 
The Novoda Craft University
The Novoda Craft UniversityThe Novoda Craft University
The Novoda Craft University
 
Android Things - Solid Foundations
Android Things - Solid FoundationsAndroid Things - Solid Foundations
Android Things - Solid Foundations
 
Survival of the Continuist
Survival of the ContinuistSurvival of the Continuist
Survival of the Continuist
 
Google I/O 2015 Android & Tech Announcements
Google I/O 2015 Android & Tech AnnouncementsGoogle I/O 2015 Android & Tech Announcements
Google I/O 2015 Android & Tech Announcements
 
Android Jam - Services & Notifications - Udacity Lesson 6
Android Jam - Services & Notifications - Udacity Lesson 6 Android Jam - Services & Notifications - Udacity Lesson 6
Android Jam - Services & Notifications - Udacity Lesson 6
 
Android Jam - Loaders - Udacity Lesson 4c
Android Jam - Loaders - Udacity Lesson 4cAndroid Jam - Loaders - Udacity Lesson 4c
Android Jam - Loaders - Udacity Lesson 4c
 
Android Jam - ContentProviders - Udacity Lesson 4b
Android Jam - ContentProviders - Udacity Lesson 4bAndroid Jam - ContentProviders - Udacity Lesson 4b
Android Jam - ContentProviders - Udacity Lesson 4b
 
Android Jam - Activity Lifecycle & Databases - Udacity Lesson 4a
Android Jam - Activity Lifecycle & Databases - Udacity Lesson 4aAndroid Jam - Activity Lifecycle & Databases - Udacity Lesson 4a
Android Jam - Activity Lifecycle & Databases - Udacity Lesson 4a
 
Y U NO CRAFTSMAN
Y U NO CRAFTSMANY U NO CRAFTSMAN
Y U NO CRAFTSMAN
 
Oh so you test? - A guide to testing on Android from Unit to Mutation
Oh so you test? - A guide to testing on Android from Unit to MutationOh so you test? - A guide to testing on Android from Unit to Mutation
Oh so you test? - A guide to testing on Android from Unit to Mutation
 
Jenkins project based authorization
Jenkins   project based authorizationJenkins   project based authorization
Jenkins project based authorization
 
Judge my gym - GymBabes Walkthrough
Judge my gym - GymBabes WalkthroughJudge my gym - GymBabes Walkthrough
Judge my gym - GymBabes Walkthrough
 
Open Closed Principle kata
Open Closed Principle kataOpen Closed Principle kata
Open Closed Principle kata
 

Recently uploaded

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 

Java Patterns - Strategy

  • 3. What is it? “Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.” Gang of Four
  • 5. Why would I use it? Strategy lets the algorithm vary independently from clients that use it Strategy pattern allows you to prefer composition over inheritance Adhere’s to the Open/Closed principle of SOLID Helps manage the complexity of having numerous variations of an algorithm
  • 6. Replacing conditional logic with the strategy pattern if(designPattern) { profit(); }
  • 8. Walkthrough Conditional logic in a variant controls which of several variants of a calculation are executed. Create a strategy for each variant and make the method delegate the calculation to a Strategy instance.
  • 9. public double capital() { if (expiry == null && maturity != null) return commitment * duration() * riskFactor(); if (expiry != null && maturity == null) { if (getUnusedPercentage() != 1) { return commitment * getUnusedPercentage() * duration() * riskFactor(); } else { return (outstandingRiskAmount() * duration() * riskFactor()) + unusedRiskAmount() * duration() * unusedRiskFactor(); } } return 0.0d; } public double capital() { return capitalStrategy.capital(this); } public double capital(Loan loan) { return loan.getCommitment() * duration(loan) * riskFactorFor(loan); }
  • 10. Loan double capital() : double Loan double capital() : double CapitalStrategy capital(loan : Loan) : double CapitalStrategyAdvisedLine capital(loan : Loan) : double CapitalStrategyRevolver capital(loan : Loan) : double CapitalStrategyTermLoan capital(loan : Loan) : double 1
  • 11. Create a Concrete Strategy public class CapitalStrategy { }
  • 12. Delegate to your Concrete Strategy public double capital() { return new CapitalStrategy().capital(this); } public double capital() { return new CapitalStrategy().capital(expiry, maturity, commitment, duration(), riskFactor()...); } Pass the context as parameter Pass the necessary data parameters
  • 13. Pass the context as parameter - Making context methods visible to obtain information, breaking ‘information hiding’ + When your class gets new public methods they’re instantly available
  • 14. Pass the necessary data parameters - All data will be passed to all strategies regardless if it needs that data + Involves the least coupling between the context and the strategy
  • 15. Pass the context as parameter public class CapitalStrategy { public double capital(Loan loan) { if (loan.getExpiry() == null && loan.getMaturity() != null) { return loan.getCommitment() * loan.duration() * riskFactorFor(loan); } if (loan.getExpiry() != null && loan.getMaturity() == null) { if (loan.getUnusedPercentage() != 1) { return loan.getCommitment() * loan.getUnusedPercentage() * loan.duration() * riskFactorFor(loan); } else { return (loan.outstandingRiskAmount() * loan.duration() * riskFactorFor(loan)) + loan.unusedRiskAmount() * loan.duration() * unusedRiskFactorFor(loan); } } return 0d; } } private double riskFactorFor(Loan loan) { return 0; } private double unusedRiskFactorFor(Loan loan) { return 0; }
  • 16. Pass the context as parameterpublic class Loan { …. public double capital() { return new CapitalStrategy().capital(this); } double duration() { return 0d; } int getUnusedPercentage() { return new Random().nextInt(1); } double outstandingRiskAmount() { return 0d; } double unusedRiskAmount() { return 0d; } Date getExpiry() { return expiry; } Date getMaturity() { return maturity; } double getCommitment() { return commitment; } }
  • 17. Move functionality related to capital calc public class CapitalStrategy { public double capital(Loan loan) { if (loan.getExpiry() == null && loan.getMaturity() != null) { return loan.getCommitment() * duration() * riskFactorFor(loan); } if (loan.getExpiry() != null && loan.getMaturity() == null) { if (getUnusedPercentage() != 1) { return loan.getCommitment() * getUnusedPercentage() * duration() * riskFactorFor(loan); } else { return (outstandingRiskAmount() * duration() * riskFactorFor(loan)) + unusedRiskAmount() * duration() * unusedRiskFactorFor(loan); } } return 0d; } ...
  • 18. Extract Field public class Loan { private final Date expiry; private final Date maturity; private final double commitment; private final CapitalStrategy strategy; public Loan(Date expiry, Date maturity, double commitment) { this.expiry = expiry; this.maturity = maturity; this.commitment = commitment; this.strategy = new CapitalStrategy(); } public double capital() { return strategy.capital(this); } ... ... Date getExpiry() { return expiry; } Date getMaturity() { return maturity; } double getCommitment() { return commitment; } }
  • 19. Extract Parameter public static Loan newTermLoad(Date expiry, Date maturity, double commitment) { return new Loan(expiry, maturity, commitment, new CapitalStrategy()); } public static Loan newRevolver(Date expiry, Date maturity, double commitment) { return new Loan(expiry, maturity, commitment, new CapitalStrategy()); } public Loan(Date expiry, Date maturity, double commitment, CapitalStrategy capitalStrategy) { this.expiry = expiry; this.maturity = maturity; this.commitment = commitment; this.strategy = capitalStrategy; }
  • 20. Replace conditional with Polymorphism public class CapitalStrategyTermLoan extends CapitalStrategy { public double capital(Loan loan) { return loan.getCommitment() * duration() * riskFactorFor(loan); } @Override protected double duration() { return 0d; // specific calculation for term loans } } public static Loan newTermLoad(Date expiry, Date maturity, double commitment) { return new Loan(expiry, maturity, commitment, new CapitalStrategyTermLoan()); }
  • 21. Replace conditional with Polymorphism public static Loan newTermLoad(Date expiry, Date maturity, double commitment) { return new Loan(expiry, maturity, commitment, new CapitalStrategyTermLoan()); } public static Loan newRevolver(Date expiry, Date maturity, double commitment) { return new Loan(expiry, maturity, commitment, new CapitalStrategyRevolver()); } public static Loan newAdvisedLine(Date expiry, Date maturity, double commitment, int riskRating) { if(riskRating > 3) return null; return new Loan(expiry, maturity, commitment, new CapitalStrategyAdvisedLine()); }
  • 22. CapitalStrategy changes public abstract class CapitalStrategy { public abstract double capital(Loan loan); protected double duration() { return 0d; // shared implementation } protected double riskFactorFor(Loan loan) { return 0d; // shared implementation } }
  • 23. image
  • 24. Benefits + Clarifies algorithms by decreasing or moving conditional logic + Simplifies a class by moving variations of an algorithm to a hierarchy + Enables one algorithm to be swapped for another at runtime
  • 25. Liabilities - Complicates a design when simpler refactorings like compose method are available - Complicates how an algorithm obtains or receives data from their context class
  • 26. image
  • 27. Alternatives Smaller changes - Compose Method - Decompose conditional More suited changes - Move embellishment to decorator - Replace conditional with polymorphism see: Refactoring to Patterns - Joshua Kerievsky
  • 28. image
  • 29. Refactoring ‘towards’ a pattern- Refactor to, towards or away - Some patterns are all or nothing - Aim is always for a better design - Evaluate if the design has improved - Pools of Insight http://www.industriallogic.com/papers/khdraft.pdf
  • 30. Further Reading Refactoring - Martin Fowler Refactoring to Patterns - Joshua Kerievsky Head First Design Patterns - Elisabeth Freeman Design Patterns - Gof https://www.goodreads.com/genres/novoda-new-starts- reading

Editor's Notes

  1. This is my strategy. There are many many like it, but this one is mine. the strategy pattern (also known as the policy pattern) The strategy pattern is the creation an inter-changeable family of algorithms interchangeable at run-time.
  2. You can think of the strategy pattern in use at a Formula One race track, the tyres are inter-changeable at runtime, they can be changed when the car comes into the pit lane depending on how the car is running, track conditions, weather, other drivers. It’s always a car but the tyre style can change.
  3. Using composition allows you to have a Car that has a normal brake strategy or a break with ABS strategy. Allowing the car to be open to extension but closed to modification. (Modification & inheritance would mean someone can subclass & override braking behavour).
  4. Enough TALK, let’s get hands on and run through a real scenario for using the Strategy Pattern.
  5. You can introduce parameter objects, or pass data through constructors
  6. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  7. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  8. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  9. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  10. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  11. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  12. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  13. Passing the context is much simpler at the moment because otherwise i’d have to pass 8+ parameters
  14. Once size does not fit all When not to use replace conditional with strategy pattern When to consider replace conditional with polymorphism
  15. Decorator & Strategy both eliminate conditional logic around special cases or alternative behaviour. If the code under inspection is part of an inheritance hierarchy each algorithm might map to one subclass. if not already inheritance you have to consider if your algorithm just depends on one type code, you might be better creating subclasses. No type code - go for strategy. Swapping algorithms at runtime, you should avoid inheritance based approaches because this would mean changing the type of the object the client is working with rather than substituting a strategy.
  16. Change is a process not an event