![Page 1: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/1.jpg)
Design Patternsin the 21st Century
15th October 2014@SamirTalwar
![Page 2: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/2.jpg)
What do you want from me?
I want you to stop using design patterns.
![Page 3: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/3.jpg)
What do you want from me?
I want you to stop using design patterns…like it’s 1999.
![Page 4: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/4.jpg)
![Page 5: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/5.jpg)
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
![Page 6: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/6.jpg)
And now, an aside, on functional programming.
![Page 7: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/7.jpg)
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); }};
![Page 8: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/8.jpg)
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);
![Page 9: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/9.jpg)
Preparation prepareCake = mmmmm -> new CakeMix(eggs, butter, sugar) .combinedWith(mmmmm);
Mix mix = new CakeMix(eggs, butter, sugar);Preparation prepareCake = mix::combinedWith;
![Page 10: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/10.jpg)
Mix mix = new CakeMix(eggs, butter, sugar); Preparation prepareCake = mix::combinedWith;
Course combinedWith(Ingredient);
@FunctionalInterfaceinterface Preparation { Course madeOf(Ingredient mmmmm);}
![Page 11: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/11.jpg)
Well.
![Page 12: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/12.jpg)
On to the Good Stuff
![Page 13: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/13.jpg)
The Abstract Factory
pattern
![Page 14: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/14.jpg)
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
![Page 15: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/15.jpg)
![Page 16: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/16.jpg)
public interface Bakery { Pastry bakePastry(Topping topping); }
public class DanishBakery implements Bakery { @Override public Pastry bakePastry(Topping topping) { return new DanishPastry(topping); }}
Abstract Factory
![Page 17: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/17.jpg)
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;
Abstract Factory
![Page 18: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/18.jpg)
package java.util.function;/** * Represents a function that * accepts one argument and produces a result. * * @since 1.8 */@FunctionalInterfacepublic interface Function<T, R> { /** * Applies this function to the given argument. */ R apply(T t); ...}
Abstract Factory
![Page 19: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/19.jpg)
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
![Page 20: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/20.jpg)
![Page 21: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/21.jpg)
The Adapterpattern
![Page 22: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/22.jpg)
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
![Page 23: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/23.jpg)
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
![Page 24: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/24.jpg)
interface Oven { Food cook(Food food);}
Oven oven = new MakeshiftOven(fire);Food bakedPie = oven.cook(pie);
Adapter
![Page 25: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/25.jpg)
![Page 26: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/26.jpg)
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
![Page 27: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/27.jpg)
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
![Page 28: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/28.jpg)
Oven oven = food -> { Burnt<Food> nastyFood = fire.burn(food); return nastyFood.scrapeOffBurntBits();};
Oven oven = food -> fire.burn(food).scrapeOffBurntBits();
Adapter
![Page 29: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/29.jpg)
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
![Page 30: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/30.jpg)
package java.util.concurrent;/** * An object that executes * submitted {@link Runnable} tasks. */public interface Executor { void execute(Runnable command);}
Adapter
![Page 31: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/31.jpg)
public interface Executor { void execute(Runnable command);}
Executor executor = ...;Stream<Runnable> tasks = ...;
tasks.forEach(executor);
Adapter
![Page 32: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/32.jpg)
public interface Stream<T> { ... void forEach(Consumer<? super T> action); ...}
@FunctionalInterfacepublic interface Consumer<T> { void accept(T t); ...}
Adapter
![Page 33: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/33.jpg)
public interface Executor { void execute(Runnable command);}@FunctionalInterfacepublic interface Consumer<T> { void accept(T t);}
Executor executor = ...;Stream<Runnable> tasks = ...;
tasks.forEach(task -> executor.execute(task));
tasks.forEach(executor::execute);
/
![Page 34: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/34.jpg)
executor::execute
Adapter
![Page 35: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/35.jpg)
![Page 36: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/36.jpg)
The Chain of Responsibility
pattern
![Page 37: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/37.jpg)
@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
![Page 38: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/38.jpg)
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
![Page 39: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/39.jpg)
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
![Page 40: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/40.jpg)
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
![Page 41: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/41.jpg)
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
![Page 42: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/42.jpg)
![Page 43: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/43.jpg)
Chain of Responsibility
Ick.
So much mutation.
Where’s the start?
What happens at the end?
![Page 44: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/44.jpg)
@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
![Page 45: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/45.jpg)
@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
![Page 46: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/46.jpg)
@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
![Page 47: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/47.jpg)
@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
![Page 48: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/48.jpg)
Chain<PieEater> pieEaters = Chain.from(alice) .to(Chain.from(bob) .to(Chain.endingWith(carol)));
(cons alice (cons bob (cons carol nil)))
Chain of Responsibility
![Page 49: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/49.jpg)
(cons alice (cons bob (cons carol nil)))
Chain of Responsibility
![Page 50: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/50.jpg)
:-O
Chain of Responsibility
![Page 51: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/51.jpg)
@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
![Page 52: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/52.jpg)
![Page 53: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/53.jpg)
So.
![Page 54: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/54.jpg)
So. What’s your point?
![Page 55: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/55.jpg)
![Page 56: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/56.jpg)
I want you to use design patterns…like it’s 1958.
![Page 57: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/57.jpg)
λ O O P
![Page 58: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/58.jpg)
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)
![Page 59: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/59.jpg)
![Page 60: Design Patterns in the 21st Century - Samir Talwar](https://reader035.vdocuments.mx/reader035/viewer/2022081401/559c45e71a28ab7e218b464a/html5/thumbnails/60.jpg)
Thank you.