Design Patterns
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Mechanism and Domain
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Patterns: Not libraries, not frameworks
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Strategy
[GoF] Gives you pluggable behaviour
Strategy is used when you have an object that needs a way to change its behaviour. Depending on configuration, or in response to external events, it needs to do some processing differently. You could do this with conditionals like switch statements. But you want to respect OCP and keep that object unmodified.
Injecting a Strategy object enables this.
As an example, employees can have different bonus schemes as they hit different targets.
Here is our Strategy pattern interface. It will allow us to make various implementations:
1 interface BonusScheme {
2 void applyTo(Money pay);
3 }
We can now inject that in our Employee objects:
1 class Employee {
2 private BonusScheme bonus ;
3
4 public Employee(BonusScheme bonus) {
5 this.bonus = bonus;
6 }
7
8 Money totalPay() {
9 Money pay = calculateBasePay();
10
11 // Use the strategy
12 bonus.applyTo(pay);
13
14 return pay;
15 }
16
17 private Money calculateBasePay() {
18 // ... code
19 }
20 }
This Employee object is now open for behaviour changes in its bonus scheme. But it is closed to modification. We don’t need to change the insides just to change a bonus scheme.
Let’s demonstrate that with two simple schemes - NoBonus and BonusTwenty
1 class NoBonus implements BonusScheme {
2 void apply(Money pay) {
3 // No Action
4 }
5 }
6
7 class BonusTwenty {
8 void apply(Money pay) {
9 pay.add(new Money("20.00"));
10 }
11 }
When we create employee objects, we inject whichever bonus scheme concrete object we want to use.
Real payment systems are more complex and would have logic in the bonus scheme. That would collaborate with other objects, like Targets perhaps, to see if we qualify. The BonusScheme objects might even get Strategy pattern objects of their own.
Strategy crops up everywhere you want to vary behaviour. In the same way a variable handles variable data, the Strategy pattern handles variable behaviour. It’s as simple as that.
Strategy can be a low-level mechanism technique. At a higher level, it can express domain ideas that have changing behaviour in the real world. The classic being Employee objects that start out as juniors but then get promoted to managers. Strategy makes for a direct model of that.
Examples: Tax Calculation, Payment schedule, Data source selection, Graphics filters, Plugins of all kinds, Extension points, Customisations, Skins, Complex rules.
Observer
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Adapter
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Command
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Composite
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Facade
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Builder
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Repository
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Query
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Simple Query Object
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
CollectingParameter
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Item-Item Description
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Moment-Interval
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Clock
[Own] Provides a way to represent current time that can be stubbed
Time driven functions need to know the actual real-world time now. Writing this, it is the 11 Nov 2020, 22:54:23 BST.
All usable systems provide a way to get real-world time. Java provides the older new Date() syntax to access the system clock. The Java 8 Joda-time inspired update provides newer features and a less zany syntax.
But both systems share the same problem. If you use them directly in your code, you are stuck with the actual time, right now, in the real world. This makes testing either hard or impossible. Recreating a production fault from logs captured earlier is impossible, too.
In both cases, we need a way to force the time to a test value.
The Clock pattern is a simple abstraction of the system clock. Using the older Date syntax for simplicity, it looks like this:
1 interface Clock {
2 Date now();
3 }
This is a Dependency Inversion (DIP). Our code now depends on only this interface for its source of the current time, using the now() method.
For production, we define a SystemClock class:
1 class SystemClock implements Clock {
2 public Date now() {
3 return new Date();
4 }
5 }
We Dependency Inject this SystemClock class to everywhere that needs to know the time. Often, this comes from a Config class that runs at application startup.
For testing, we inject a stub class:
1 class StubClock implements Clock {
2 private Date date ;
3
4 public Date now() {
5 return date ;
6 }
7
8 public void setTo( Date d ) {
9 this.date = d;
10 }
11
12 public void oneHourLater() {
13 // code to go forward one hour
14 }
15
16 public void oneHourEarlier() {
17 // code to go back one hour
18 }
19 }
This stub has features to set to a specific time, then move to an hour later or earlier. You would change these to your specific test requirements. The idea is that you are creating a Domain Specific Language (DSL) about test times, to make your test code into readable documentation.
This is one of those insanely useful patterns that it is actually muscle memory for me.
Rules (or Policy)
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Aggregate
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Cache
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Decorator
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
External System (Proxy)
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Configuration
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Order-OrderLineItem
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Request-Service-Response
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Anti-Patterns
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Design Pattern Soup
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Unneeded Flexibility
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.
Mechanism Madness
This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/javaoopdoneright.