+ All Categories
Home > Presentations & Public Speaking > Design Patterns in the 21st Century - Samir Talwar

Design Patterns in the 21st Century - Samir Talwar

Date post: 08-Jul-2015
Category:
Upload: jaxlondon2014
View: 175 times
Download: 0 times
Share this document with a friend
Description:
JAX London Presentation 2014
60
Design Patterns in the 21 st Century 15 th October 2014 @SamirTalwar
Transcript
Page 1: Design Patterns in the 21st Century - Samir Talwar

Design Patternsin the 21st Century

15th October 2014@SamirTalwar

Page 2: Design Patterns in the 21st Century - Samir Talwar

What do you want from me?

I want you to stop using design patterns.

Page 3: Design Patterns in the 21st Century - Samir Talwar

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
Page 5: 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

Page 6: Design Patterns in the 21st Century - Samir Talwar

And now, an aside, on functional programming.

Page 7: Design Patterns in the 21st Century - Samir Talwar

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

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

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

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

Well.

Page 12: Design Patterns in the 21st Century - Samir Talwar

On to the Good Stuff

Page 13: Design Patterns in the 21st Century - Samir Talwar

The Abstract Factory

pattern

Page 14: Design Patterns in the 21st Century - Samir Talwar

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
Page 16: 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

Page 17: Design Patterns in the 21st Century - Samir Talwar

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

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

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
Page 21: Design Patterns in the 21st Century - Samir Talwar

The Adapterpattern

Page 22: Design Patterns in the 21st Century - Samir Talwar

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

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

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
Page 26: 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

Page 27: Design Patterns in the 21st Century - Samir Talwar

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

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

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

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

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

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

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

executor::execute

Adapter

Page 35: Design Patterns in the 21st Century - Samir Talwar
Page 36: Design Patterns in the 21st Century - Samir Talwar

The Chain of Responsibility

pattern

Page 37: Design Patterns in the 21st Century - Samir Talwar

@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

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

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

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

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
Page 43: Design Patterns in the 21st Century - Samir Talwar

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

@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

@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

@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

@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

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

(cons alice (cons bob (cons carol nil)))

Chain of Responsibility

Page 50: Design Patterns in the 21st Century - Samir Talwar

:-O

Chain of Responsibility

Page 51: Design Patterns in the 21st Century - Samir Talwar

@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
Page 53: Design Patterns in the 21st Century - Samir Talwar

So.

Page 54: Design Patterns in the 21st Century - Samir Talwar

So. What’s your point?

Page 55: Design Patterns in the 21st Century - Samir Talwar
Page 56: Design Patterns in the 21st Century - Samir Talwar

I want you to use design patterns…like it’s 1958.

Page 57: Design Patterns in the 21st Century - Samir Talwar

λ O O P

Page 59: Design Patterns in the 21st Century - Samir Talwar
Page 60: Design Patterns in the 21st Century - Samir Talwar

Thank you.


Recommended