SlideShare a Scribd company logo
Design Patterns 
in the 21st Century 
15th October 2014 
@SamirTalwar
What do you want 
from me? 
I want you to stop using design patterns.
What do you want 
from me? 
I want you to stop using design patterns… 
like it’s 1999.
Design Patterns in the 21st Century - Samir Talwar
The elements of this language are entities 
called patterns. Each pattern describes a 
problem that occurs over and over again in our 
environment, and then describes the core of the 
solution to that problem, in such a way that you 
can use this solution a million times over, 
without ever doing it the same way twice. 
– Christopher Alexander
And now, an aside, on 
functional programming.
int courses = 3; 
Course dessert = 
prepareCake.madeOf(chocolate); 
Preparation prepareCake = new Preparation() { 
@Override 
public Course madeOf(Ingredient mmmmm) { 
return 
new CakeMix(eggs, butter, sugar) 
.combinedWith(mmmmm); 
} 
};
Preparation prepareCake = new Preparation() { 
@Override 
public Course madeOf(Ingredient mmmmm) { 
return 
new CakeMix(eggs, butter, sugar) 
.combinedWith(mmmmm); 
} 
}; 
Preparation prepareCake = 
mmmmm -> 
new CakeMix(eggs, butter, sugar) 
.combinedWith(mmmmm);
Preparation prepareCake = 
mmmmm -> 
new CakeMix(eggs, butter, sugar) 
.combinedWith(mmmmm); 
Mix mix = new CakeMix(eggs, butter, sugar); 
Preparation prepareCake = 
mix::combinedWith;
Mix mix = new CakeMix(eggs, butter, sugar); 
Preparation prepareCake = 
mix::combinedWith; 
Course combinedWith(Ingredient); 
@FunctionalInterface 
interface Preparation { 
Course madeOf(Ingredient mmmmm); 
}
Well.
On to the Good Stuff
The 
Abstract Factory 
pattern
public interface Bakery { 
Pastry bakePastry(Topping topping); 
Cake bakeCake(); 
} 
public class DanishBakery implements Bakery { 
@Override 
public Pastry bakePastry(Topping topping) { 
return new DanishPastry(topping); 
} 
@Override 
public Cake bakeCake() { 
return new Æblekage(); // mmmm, apple cake… 
} 
} 
Abstract Factory
Design Patterns in the 21st Century - Samir Talwar
public interface Bakery { 
Pastry bakePastry(Topping topping); 
} 
public class DanishBakery implements Bakery { 
@Override 
public Pastry bakePastry(Topping topping) { 
return new DanishPastry(topping); 
} 
} 
Abstract Factory
Abstract Factory 
public class DanishBakery implements Bakery { 
@Override 
public Pastry bakePastry(Topping topping) { 
return new DanishPastry(topping); 
} 
} 
Bakery danishBakery = topping -> 
new DanishPastry(topping); 
Bakery danishBakery = DanishPastry::new;
package java.util.function; 
/** 
* Represents a function that 
* accepts one argument and produces a result. 
* 
* @since 1.8 
*/ 
@FunctionalInterface 
public interface Function<T, R> { 
/** 
* Applies this function to the given 
argument. 
*/ 
R apply(T t); 
... 
} 
Abstract Factory
public class DanishBakery 
implements Function<Topping, Pastry> { 
@Override 
public Pastry apply(Topping topping) { 
return new DanishPastry(topping); 
} 
} 
Function<Topping, Pastry> danishBakery 
= topping -> 
new DanishPastry(topping); 
Function<Topping, Pastry> danishBakery 
= DanishPastry::new; 
Abstract Factory
Design Patterns in the 21st Century - Samir Talwar
The 
Adapter 
pattern
interface Fire { 
<T> Burnt<T> burn(T thing); 
} 
interface Oven { 
Food cook(Food food); 
} 
class WoodFire implements Fire { ... } 
class MakeshiftOven 
extends WoodFire 
implements Oven { 
@Override public Food cook(Food food) { 
Burnt<Food> nastyFood = burn(food); 
return nastyFood.scrapeOffBurntBits(); 
} 
} 
Adapter
interface Fire { 
<T> Burnt<T> burn(T thing); 
} 
interface Oven { 
Food cook(Food food); 
} 
class MakeshiftOven implements Oven { 
private final Fire fire; 
public MakeshiftOven(Fire fire) { /* ... */ } 
@Override public Food cook(Food food) { 
Burnt<Food> nastyFood = fire.burn(food); 
return nastyFood.scrapeOffBurntBits(); 
} 
} 
Adapter
interface Oven { 
Food cook(Food food); 
} 
Oven oven = new MakeshiftOven(fire); 
Food bakedPie = oven.cook(pie); 
Adapter
Design Patterns in the 21st Century - Samir Talwar
interface Oven { 
Food cook(Food food); 
} 
class MakeshiftOven implements Oven { 
private final Fire fire; 
public MakeshiftOven(Fire fire) { /* ... */ } 
@Override public Food cook(Food food) { 
Burnt<Food> nastyFood = fire.burn(food); 
return nastyFood.scrapeOffBurntBits(); 
} 
} 
Adapter
class MakeshiftOven implements Oven { 
private final Fire fire; 
public MakeshiftOven(Fire fire) { /* ... */ } 
@Override public Food cook(Food food) { 
Burnt<Food> nastyFood = fire.burn(food); 
return nastyFood.scrapeOffBurntBits(); 
} 
} 
Oven oven = food -> { 
Burnt<Food> nastyFood = fire.burn(food); 
return nastyFood.scrapeOffBurntBits(); 
}; 
Food bakedPie = oven.cook(pie); 
Adapter
Oven oven = food -> { 
Adapter 
Burnt<Food> nastyFood = fire.burn(food); 
return nastyFood.scrapeOffBurntBits(); 
}; 
Oven oven = food -> 
fire.burn(food).scrapeOffBurntBits();
Oven oven = food -> 
fire.burn(food).scrapeOffBurntBits(); 
// Do *not* do this. 
Function<Food, Burnt<Food>> burn 
= fire::burn; 
Function<Food, Food> cook 
= burn.andThen(Burnt::scrapeOffBurntBits); 
Oven oven = cook::apply; 
Food bakedPie = oven.cook(pie); 
Adapter
package java.util.concurrent; 
/** 
* An object that executes 
* submitted {@link Runnable} tasks. 
*/ 
public interface Executor { 
void execute(Runnable command); 
} 
Adapter
public interface Executor { 
void execute(Runnable command); 
} 
Executor executor = ...; 
Stream<Runnable> tasks = ...; 
tasks.forEach(executor); 
Adapter
public interface Stream<T> { 
... 
void forEach(Consumer<? super T> action); 
... 
} 
@FunctionalInterface 
public interface Consumer<T> { 
void accept(T t); 
... 
} 
Adapter
public interface Executor { 
void execute(Runnable command); 
} 
@FunctionalInterface 
public interface Consumer<T> { 
void accept(T t); 
} 
Executor executor = ...; 
Stream<Runnable> tasks = ...; 
tasks.forEach(task -> executor.execute(task)); 
tasks.forEach(executor::execute); 
/
executor::execute 
Adapter
Design Patterns in the 21st Century - Samir Talwar
The 
Chain of Responsibility 
pattern
@Test public void whoAteMyPie() { 
PieEater alice = PieEater.whoLoves(APPLE); 
PieEater bob = PieEater.whoLoves(BLUEBERRY); 
PieEater carol = PieEater.whoLoves(CHERRY); 
alice.setNext(bob); 
bob.setNext(carol); 
alice.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
public final class HitCounterFilter implements Filter { 
private FilterConfig filterConfig = null; 
public void init(FilterConfig filterConfig) throws ServletException { 
this.filterConfig = filterConfig; 
} 
public void destroy() { 
this.filterConfig = null; 
} 
public void doFilter 
(ServletRequest request, ServletResponse response, FilterChain chain) 
throws IOException, ServletException { 
if (filterConfig == null) 
return; 
Counter counter = 
(Counter)filterConfig.getServletContext().getAttribute("hitCounter"); 
StringWriter sw = new StringWriter(); 
PrintWriter writer = new PrintWriter(sw); 
writer.println("The number of hits is: " + counter.incCounter()); 
writer.flush(); 
filterConfig.getServletContext().log(sw.getBuffer().toString()); 
chain.doFilter(request, response); 
} 
} 
Chain of 
Responsibility
public final class HitCounterFilter 
implements Filter { 
// init and destroy 
public void doFilter( 
ServletRequest request, 
ServletResponse response, 
FilterChain chain) { 
int hits = getCounter().incCounter(); 
log(“The number of hits is ” + hits); 
chain.doFilter(request, response); 
} 
} 
Chain of 
Responsibility
public final class SwitchEncodingFilter 
implements Filter { 
// init and destroy 
public void doFilter( 
ServletRequest request, 
ServletResponse response, 
FilterChain chain) { 
request.setEncoding(“UTF-8”); 
chain.doFilter(request, response); 
} 
} 
Chain of 
Responsibility
public final class AuthorizationFilter 
implements Filter { 
// init and destroy 
public void doFilter( 
ServletRequest request, 
ServletResponse response, 
FilterChain chain) { 
if (!user().canAccess(request)) 
throw new AuthException(user); 
chain.doFilter(request, response); 
} 
} 
Chain of 
Responsibility
Design Patterns in the 21st Century - Samir Talwar
Chain of 
Responsibility 
Ick. 
So much mutation. 
Where’s the start? 
What happens at the end?
@Test public void whoAteMyPie() { 
PieEater alice = PieEater.whoLoves(APPLE); 
PieEater bob = PieEater.whoLoves(BLUEBERRY); 
PieEater carol = PieEater.whoLoves(CHERRY); 
alice.setNext(bob); 
bob.setNext(carol); 
alice.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
@Test public void whoAteMyPie() { 
PieEater carol = PieEater.atTheEnd() 
.whoLoves(CHERRY); 
PieEater bob = PieEater.before(carol) 
.whoLoves(BLUEBERRY); 
PieEater alice = PieEater.before(bob) 
.whoLoves(APPLE); 
alice.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
@Test public void whoAteMyPie() { 
Chain<PieEater> carol = 
Chain.endingWith(PieEater.whoLoves(CHERRY)); 
Chain<PieEater> bob = 
Chain.from(PieEater.whoLoves(BLUEBERRY)) 
.to(carol); 
Chain<PieEater> alice = 
Chain.from(PieEater.whoLoves(APPLE)) 
.to(bob); 
alice.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
@Test public void whoAteMyPie() { 
PieEater alice = PieEater.whoLoves(APPLE); 
PieEater bob = PieEater.whoLoves(BLUEBERRY); 
PieEater carol = PieEater.whoLoves(CHERRY); 
Chain<PieEater> pieEaters = 
Chain.from(alice) 
.to(Chain.from(bob) 
.to(Chain.endingWith(carol))); 
pieEaters.find(person -> person.loves(BLUEBERRY)) 
.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
Chain<PieEater> pieEaters = 
Chain.from(alice) 
.to(Chain.from(bob) 
Chain of 
Responsibility 
.to(Chain.endingWith(carol))); 
(cons alice (cons bob (cons carol nil)))
Chain of 
Responsibility 
(cons alice (cons bob (cons carol nil)))
:-O 
Chain of 
Responsibility
@Test public void whoAteMyPie() { 
PieEater alice = PieEater.whoLoves(APPLE); 
PieEater bob = PieEater.whoLoves(BLUEBERRY); 
PieEater carol = PieEater.whoLoves(CHERRY); 
Stream<PieEater> pieEaters 
= Stream.of(alice, bob, carol); 
pieEaters 
.findAny(person -> person.loves(BLUEBERRY)) 
.get() 
.give(blueberryPie); 
assertThat(bob, ate(blueberryPie)); 
} 
Chain of 
Responsibility
Design Patterns in the 21st Century - Samir Talwar
So.
So. What’s your point?
Design Patterns in the 21st Century - Samir Talwar
I want you to use design patterns… 
like it’s 1958.
λ O O P
Credits 
Bakery, by Boris Bartels 
Just baked, by Sergio Russo 
cherry pie with crumble topping, by Ginny 
This presentation is licensed under 
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
Design Patterns in the 21st Century - Samir Talwar
Thank you.

More Related Content

PDF
Design patterns in the 21st Century
PDF
Kotlin Generation
PDF
Transaction is a monad
PPT
Swiss army knife Spring
PDF
The Ring programming language version 1.5.4 book - Part 79 of 185
KEY
Android workshop
PDF
The Ring programming language version 1.2 book - Part 16 of 84
PDF
Java 8 - Nuts and Bold - SFEIR Benelux
Design patterns in the 21st Century
Kotlin Generation
Transaction is a monad
Swiss army knife Spring
The Ring programming language version 1.5.4 book - Part 79 of 185
Android workshop
The Ring programming language version 1.2 book - Part 16 of 84
Java 8 - Nuts and Bold - SFEIR Benelux

Similar to Design Patterns in the 21st Century - Samir Talwar (20)

PDF
Design patterns
PPTX
Solid principles
PPTX
Creational pattern 2
PDF
Mieux programmer grâce aux design patterns
ODP
Factory Method Pattern
PPTX
Software System Architecture-Lecture 6.pptx
PDF
The Basic Concept Of IOC
PPTX
Abstract Factory Pattern (Example & Implementation in Java)
PPTX
Abstract Factory Design Pattern
PPT
Factory and Abstract Factory
PPTX
Design patterns(red)
PPTX
Design patterns
PPTX
L09 Frameworks
PPTX
gffhfghfgchfygnghS09-Design-Patterns.pptx
PPTX
Behavioral pattern 4
PPTX
L04 base patterns
PPTX
Factory method, strategy pattern & chain of responsibilities
PDF
Functional Design Patterns (DevTernity 2018)
PDF
Factory patterns
PPTX
Iterative architecture
Design patterns
Solid principles
Creational pattern 2
Mieux programmer grâce aux design patterns
Factory Method Pattern
Software System Architecture-Lecture 6.pptx
The Basic Concept Of IOC
Abstract Factory Pattern (Example & Implementation in Java)
Abstract Factory Design Pattern
Factory and Abstract Factory
Design patterns(red)
Design patterns
L09 Frameworks
gffhfghfgchfygnghS09-Design-Patterns.pptx
Behavioral pattern 4
L04 base patterns
Factory method, strategy pattern & chain of responsibilities
Functional Design Patterns (DevTernity 2018)
Factory patterns
Iterative architecture
Ad

More from JAXLondon2014 (20)

PDF
GridGain 6.0: Open Source In-Memory Computing Platform - Nikita Ivanov
PDF
Performance Metrics for your Delivery Pipeline - Wolfgang Gottesheim
PPTX
How to randomly access data in close-to-RAM speeds but a lower cost with SSD’...
PDF
Conditional Logging Considered Harmful - Sean Reilly
PDF
Finding your Way in the Midst of the NoSQL Haze - Abdelmonaim Remani
PPT
API Management - a hands on workshop - Paul Fremantle
PDF
'Bootiful' Code with Spring Boot - Josh Long
PDF
The Full Stack Java Developer - Josh Long
PDF
The Economies of Scaling Software - Josh Long and Abdelmonaim Remani
PDF
Dataflow, the Forgotten Way - Russel Winder
PDF
Habits of Highly Effective Technical Teams - Martijn Verburg
PDF
The Lazy Developer's Guide to Cloud Foundry - Holly Cummins
PPTX
Testing within an Agile Environment - Beyza Sakir and Chris Gollop
PDF
Testing the Enterprise Layers - the A, B, C's of Integration Testing - Aslak ...
PDF
Squeezing Performance of out of In-Memory Data Grids - Fuad Malikov
PDF
Spocktacular Testing - Russel Winder
PDF
Server Side JavaScript on the Java Platform - David Delabassee
PDF
Reflection Madness - Dr. Heinz Kabutz
PDF
Rapid Web Application Development with MongoDB and the JVM - Trisha Gee
PDF
Pushing Java EE outside of the Enterprise: Home Automation and IoT - David De...
GridGain 6.0: Open Source In-Memory Computing Platform - Nikita Ivanov
Performance Metrics for your Delivery Pipeline - Wolfgang Gottesheim
How to randomly access data in close-to-RAM speeds but a lower cost with SSD’...
Conditional Logging Considered Harmful - Sean Reilly
Finding your Way in the Midst of the NoSQL Haze - Abdelmonaim Remani
API Management - a hands on workshop - Paul Fremantle
'Bootiful' Code with Spring Boot - Josh Long
The Full Stack Java Developer - Josh Long
The Economies of Scaling Software - Josh Long and Abdelmonaim Remani
Dataflow, the Forgotten Way - Russel Winder
Habits of Highly Effective Technical Teams - Martijn Verburg
The Lazy Developer's Guide to Cloud Foundry - Holly Cummins
Testing within an Agile Environment - Beyza Sakir and Chris Gollop
Testing the Enterprise Layers - the A, B, C's of Integration Testing - Aslak ...
Squeezing Performance of out of In-Memory Data Grids - Fuad Malikov
Spocktacular Testing - Russel Winder
Server Side JavaScript on the Java Platform - David Delabassee
Reflection Madness - Dr. Heinz Kabutz
Rapid Web Application Development with MongoDB and the JVM - Trisha Gee
Pushing Java EE outside of the Enterprise: Home Automation and IoT - David De...
Ad

Recently uploaded (20)

PPTX
MERISTEMATIC TISSUES (MERISTEMS) PPT PUBLIC
PDF
MODULE 3 BASIC SECURITY DUTIES AND ROLES.pdf
PPTX
Research Process - Research Methods course
PPTX
Tour Presentation Educational Activity.pptx
PPTX
AcademyNaturalLanguageProcessing-EN-ILT-M02-Introduction.pptx
PPTX
The Effect of Human Resource Management Practice on Organizational Performanc...
PPTX
Effective_Handling_Information_Presentation.pptx
PPTX
Sustainable Forest Management ..SFM.pptx
PDF
Microsoft-365-Administrator-s-Guide_.pdf
PPTX
_ISO_Presentation_ISO 9001 and 45001.pptx
PPTX
PurpoaiveCommunication for students 02.pptx
PPTX
Project and change Managment: short video sequences for IBA
PPTX
chapter8-180915055454bycuufucdghrwtrt.pptx
PPTX
Self management and self evaluation presentation
PPTX
3RD-Q 2022_EMPLOYEE RELATION - Copy.pptx
PPTX
Lesson-7-Gas. -Exchange_074636.pptx
DOC
LSTM毕业证学历认证,利物浦大学毕业证学历认证怎么认证
PDF
PM Narendra Modi's speech from Red Fort on 79th Independence Day.pdf
PPTX
2025-08-10 Joseph 02 (shared slides).pptx
PPTX
Hydrogel Based delivery Cancer Treatment
MERISTEMATIC TISSUES (MERISTEMS) PPT PUBLIC
MODULE 3 BASIC SECURITY DUTIES AND ROLES.pdf
Research Process - Research Methods course
Tour Presentation Educational Activity.pptx
AcademyNaturalLanguageProcessing-EN-ILT-M02-Introduction.pptx
The Effect of Human Resource Management Practice on Organizational Performanc...
Effective_Handling_Information_Presentation.pptx
Sustainable Forest Management ..SFM.pptx
Microsoft-365-Administrator-s-Guide_.pdf
_ISO_Presentation_ISO 9001 and 45001.pptx
PurpoaiveCommunication for students 02.pptx
Project and change Managment: short video sequences for IBA
chapter8-180915055454bycuufucdghrwtrt.pptx
Self management and self evaluation presentation
3RD-Q 2022_EMPLOYEE RELATION - Copy.pptx
Lesson-7-Gas. -Exchange_074636.pptx
LSTM毕业证学历认证,利物浦大学毕业证学历认证怎么认证
PM Narendra Modi's speech from Red Fort on 79th Independence Day.pdf
2025-08-10 Joseph 02 (shared slides).pptx
Hydrogel Based delivery Cancer Treatment

Design Patterns in the 21st Century - Samir Talwar

  • 1. Design Patterns in the 21st Century 15th October 2014 @SamirTalwar
  • 2. What do you want from me? I want you to stop using design patterns.
  • 3. What do you want from me? I want you to stop using design patterns… like it’s 1999.
  • 5. The elements of this language are entities called patterns. Each pattern describes a problem that occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice. – Christopher Alexander
  • 6. And now, an aside, on functional programming.
  • 7. int courses = 3; Course dessert = prepareCake.madeOf(chocolate); Preparation prepareCake = new Preparation() { @Override public Course madeOf(Ingredient mmmmm) { return new CakeMix(eggs, butter, sugar) .combinedWith(mmmmm); } };
  • 8. Preparation prepareCake = new Preparation() { @Override public Course madeOf(Ingredient mmmmm) { return new CakeMix(eggs, butter, sugar) .combinedWith(mmmmm); } }; Preparation prepareCake = mmmmm -> new CakeMix(eggs, butter, sugar) .combinedWith(mmmmm);
  • 9. Preparation prepareCake = mmmmm -> new CakeMix(eggs, butter, sugar) .combinedWith(mmmmm); Mix mix = new CakeMix(eggs, butter, sugar); Preparation prepareCake = mix::combinedWith;
  • 10. Mix mix = new CakeMix(eggs, butter, sugar); Preparation prepareCake = mix::combinedWith; Course combinedWith(Ingredient); @FunctionalInterface interface Preparation { Course madeOf(Ingredient mmmmm); }
  • 11. Well.
  • 12. On to the Good Stuff
  • 14. public interface Bakery { Pastry bakePastry(Topping topping); Cake bakeCake(); } public class DanishBakery implements Bakery { @Override public Pastry bakePastry(Topping topping) { return new DanishPastry(topping); } @Override public Cake bakeCake() { return new Æblekage(); // mmmm, apple cake… } } Abstract Factory
  • 16. public interface Bakery { Pastry bakePastry(Topping topping); } public class DanishBakery implements Bakery { @Override public Pastry bakePastry(Topping topping) { return new DanishPastry(topping); } } Abstract Factory
  • 17. Abstract Factory public class DanishBakery implements Bakery { @Override public Pastry bakePastry(Topping topping) { return new DanishPastry(topping); } } Bakery danishBakery = topping -> new DanishPastry(topping); Bakery danishBakery = DanishPastry::new;
  • 18. package java.util.function; /** * Represents a function that * accepts one argument and produces a result. * * @since 1.8 */ @FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. */ R apply(T t); ... } Abstract Factory
  • 19. public class DanishBakery implements Function<Topping, Pastry> { @Override public Pastry apply(Topping topping) { return new DanishPastry(topping); } } Function<Topping, Pastry> danishBakery = topping -> new DanishPastry(topping); Function<Topping, Pastry> danishBakery = DanishPastry::new; Abstract Factory
  • 22. interface Fire { <T> Burnt<T> burn(T thing); } interface Oven { Food cook(Food food); } class WoodFire implements Fire { ... } class MakeshiftOven extends WoodFire implements Oven { @Override public Food cook(Food food) { Burnt<Food> nastyFood = burn(food); return nastyFood.scrapeOffBurntBits(); } } Adapter
  • 23. interface Fire { <T> Burnt<T> burn(T thing); } interface Oven { Food cook(Food food); } class MakeshiftOven implements Oven { private final Fire fire; public MakeshiftOven(Fire fire) { /* ... */ } @Override public Food cook(Food food) { Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits(); } } Adapter
  • 24. interface Oven { Food cook(Food food); } Oven oven = new MakeshiftOven(fire); Food bakedPie = oven.cook(pie); Adapter
  • 26. interface Oven { Food cook(Food food); } class MakeshiftOven implements Oven { private final Fire fire; public MakeshiftOven(Fire fire) { /* ... */ } @Override public Food cook(Food food) { Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits(); } } Adapter
  • 27. class MakeshiftOven implements Oven { private final Fire fire; public MakeshiftOven(Fire fire) { /* ... */ } @Override public Food cook(Food food) { Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits(); } } Oven oven = food -> { Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits(); }; Food bakedPie = oven.cook(pie); Adapter
  • 28. Oven oven = food -> { Adapter Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits(); }; Oven oven = food -> fire.burn(food).scrapeOffBurntBits();
  • 29. Oven oven = food -> fire.burn(food).scrapeOffBurntBits(); // Do *not* do this. Function<Food, Burnt<Food>> burn = fire::burn; Function<Food, Food> cook = burn.andThen(Burnt::scrapeOffBurntBits); Oven oven = cook::apply; Food bakedPie = oven.cook(pie); Adapter
  • 30. package java.util.concurrent; /** * An object that executes * submitted {@link Runnable} tasks. */ public interface Executor { void execute(Runnable command); } Adapter
  • 31. public interface Executor { void execute(Runnable command); } Executor executor = ...; Stream<Runnable> tasks = ...; tasks.forEach(executor); Adapter
  • 32. public interface Stream<T> { ... void forEach(Consumer<? super T> action); ... } @FunctionalInterface public interface Consumer<T> { void accept(T t); ... } Adapter
  • 33. public interface Executor { void execute(Runnable command); } @FunctionalInterface public interface Consumer<T> { void accept(T t); } Executor executor = ...; Stream<Runnable> tasks = ...; tasks.forEach(task -> executor.execute(task)); tasks.forEach(executor::execute); /
  • 36. The Chain of Responsibility pattern
  • 37. @Test public void whoAteMyPie() { PieEater alice = PieEater.whoLoves(APPLE); PieEater bob = PieEater.whoLoves(BLUEBERRY); PieEater carol = PieEater.whoLoves(CHERRY); alice.setNext(bob); bob.setNext(carol); alice.give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 38. public final class HitCounterFilter implements Filter { private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void destroy() { this.filterConfig = null; } public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (filterConfig == null) return; Counter counter = (Counter)filterConfig.getServletContext().getAttribute("hitCounter"); StringWriter sw = new StringWriter(); PrintWriter writer = new PrintWriter(sw); writer.println("The number of hits is: " + counter.incCounter()); writer.flush(); filterConfig.getServletContext().log(sw.getBuffer().toString()); chain.doFilter(request, response); } } Chain of Responsibility
  • 39. public final class HitCounterFilter implements Filter { // init and destroy public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) { int hits = getCounter().incCounter(); log(“The number of hits is ” + hits); chain.doFilter(request, response); } } Chain of Responsibility
  • 40. public final class SwitchEncodingFilter implements Filter { // init and destroy public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) { request.setEncoding(“UTF-8”); chain.doFilter(request, response); } } Chain of Responsibility
  • 41. public final class AuthorizationFilter implements Filter { // init and destroy public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) { if (!user().canAccess(request)) throw new AuthException(user); chain.doFilter(request, response); } } Chain of Responsibility
  • 43. Chain of Responsibility Ick. So much mutation. Where’s the start? What happens at the end?
  • 44. @Test public void whoAteMyPie() { PieEater alice = PieEater.whoLoves(APPLE); PieEater bob = PieEater.whoLoves(BLUEBERRY); PieEater carol = PieEater.whoLoves(CHERRY); alice.setNext(bob); bob.setNext(carol); alice.give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 45. @Test public void whoAteMyPie() { PieEater carol = PieEater.atTheEnd() .whoLoves(CHERRY); PieEater bob = PieEater.before(carol) .whoLoves(BLUEBERRY); PieEater alice = PieEater.before(bob) .whoLoves(APPLE); alice.give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 46. @Test public void whoAteMyPie() { Chain<PieEater> carol = Chain.endingWith(PieEater.whoLoves(CHERRY)); Chain<PieEater> bob = Chain.from(PieEater.whoLoves(BLUEBERRY)) .to(carol); Chain<PieEater> alice = Chain.from(PieEater.whoLoves(APPLE)) .to(bob); alice.give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 47. @Test public void whoAteMyPie() { PieEater alice = PieEater.whoLoves(APPLE); PieEater bob = PieEater.whoLoves(BLUEBERRY); PieEater carol = PieEater.whoLoves(CHERRY); Chain<PieEater> pieEaters = Chain.from(alice) .to(Chain.from(bob) .to(Chain.endingWith(carol))); pieEaters.find(person -> person.loves(BLUEBERRY)) .give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 48. Chain<PieEater> pieEaters = Chain.from(alice) .to(Chain.from(bob) Chain of Responsibility .to(Chain.endingWith(carol))); (cons alice (cons bob (cons carol nil)))
  • 49. Chain of Responsibility (cons alice (cons bob (cons carol nil)))
  • 50. :-O Chain of Responsibility
  • 51. @Test public void whoAteMyPie() { PieEater alice = PieEater.whoLoves(APPLE); PieEater bob = PieEater.whoLoves(BLUEBERRY); PieEater carol = PieEater.whoLoves(CHERRY); Stream<PieEater> pieEaters = Stream.of(alice, bob, carol); pieEaters .findAny(person -> person.loves(BLUEBERRY)) .get() .give(blueberryPie); assertThat(bob, ate(blueberryPie)); } Chain of Responsibility
  • 53. So.
  • 56. I want you to use design patterns… like it’s 1958.
  • 57. λ O O P
  • 58. Credits Bakery, by Boris Bartels Just baked, by Sergio Russo cherry pie with crumble topping, by Ginny This presentation is licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)