Java day2016 "Reinventing design patterns with java 8"

Post on 16-Jan-2017

68 views 2 download

Transcript of Java day2016 "Reinventing design patterns with java 8"

www.luxoft.com

REINVENTING DESIGN PATTERNS WITH JAVA8

Alexander Pashynskiy

Java Day 2016

www.luxoft.com

About me:

•  Lead Software Engineer in Luxoft

•  More then 6 years experience in Java

•  Agile and Lean practicioner

•  Pragmatic and product oriented engineer

•  Still learning and learn

Email: hunter041@gmail.com

Twitter: @apashinskiy_cv

Alexander Pashinskiy

www.luxoft.com

It’s my own experience…

Disclaimer

www.luxoft.com

https://github.com/hunter1041/design-patterns

Samples:

www.luxoft.com

Design Patterns

www.luxoft.com

www.luxoft.com

www.luxoft.com

Not only

www.luxoft.com

Not only Many, many more ...

www.luxoft.com

•  OOP (Resource acquisition is initialization, Servant, DI, Pool Objects, Null object …)

•  FP (Functions, Monads, Lenz, Curring, …)

•  Concurrency (Double-checked locking, Read-write lock, Thread-specific storage, …)

•  Domain Specific (security, money, …)

•  and many, many more

www.luxoft.com

•  Problem - Solution pairs •  Similar (or same) solution - different intention (Strategy,

State …) •  inheritance - composition game (OOP) •  Adding level of indirection •  Almost always trade-off

Design Patterns:

www.luxoft.com

•  1994 year •  For C++ •  OOP

Two main principles: •  "Program to an interface, not an implementation." •  "Favor object composition over class inheritance." Sad:( Some GoF patterns do not stick to this principles

www.luxoft.com

Evolution

www.luxoft.com

Lambda -> lightwaight design tool

www.luxoft.com

Template method

www.luxoft.com

Template method

Type: behavioral

Definition: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

www.luxoft.com

•  Not only for data •  BLSP •  Violates “Single Responsibility” and encapsulation •  High Coupling •  Future behavior and frameworks inhereted •  Broken “protected” in Java •  Big hierarchy produces hell

Inheritance

www.luxoft.com

Template method

•  Inheritance is evil •  Use composition •  Part of an algorithm can be passed as a function •  Utilize basic functional interfaces •  Use function composition if possible

www.luxoft.com

Template method

inheritance -> composition -> function composition

www.luxoft.com

Template method

g.filterMailBox(f)

* Not strongly mathematical composition (contains ‘if’ logic)

www.luxoft.com

Template method

www.luxoft.com

Decorator

www.luxoft.com

Decorator

Type: structural

Definition: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

www.luxoft.com

Decorator

just a function composition

g.andThen(f)

www.luxoft.com

Decorator

www.luxoft.com

Chain of Responsibility

www.luxoft.com

Chain of Responsibility

Type: behavioral

Definition: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

www.luxoft.com

Chain of Responsibility

chain of function composition

andThen andThen andThen andThen andThen

www.luxoft.com

Chain of Responsibility

www.luxoft.com

Adapter

www.luxoft.com

Adapter

Type: structural

Definition: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

www.luxoft.com

Adapter

•  Utilise basic functional interfaces •  Functional interfaces are interchangable •  For different numbers of parameters - partially applied

function

www.luxoft.com

Partially applied function

IntBinaryOperator add = (x, y) -> x + y ; IntUnaryOperator add5 = x -> add.applyAsInt(x, 5);

Partial application - process of transforming a function into a function with less parameters.

www.luxoft.com

Partially applied function

Supported by java - :: operator

ToIntFunctiont<String> stringLength = String::length;

IntFunction<String> helloSubstring = "hello"::substring;

www.luxoft.com

Partial application

•  allows to set some (not all) parameters

•  let the other parameters to be set later

•  partially applied function can be reused and composed

•  Powerful decoupling tool

www.luxoft.com

Adapter

www.luxoft.com

Proxy

www.luxoft.com

Proxy

Type: structural

Definition: Provide a surrogate or placeholder for another object to control access to it.

www.luxoft.com

Proxy

•  Resource managing •  Transactions •  Logging •  and more ...

www.luxoft.com

Libs to create Proxy

•  java.lang.reflect.Proxy •  Byte Buddy •  cglib •  javassist

www.luxoft.com

Proxy

•  function composition •  wrap a lambda •  inverse of control – resource leasing

www.luxoft.com

Proxy

www.luxoft.com

Proxy

www.luxoft.com

Strategy

www.luxoft.com

Strategy

Type: behavioral

Definition: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

www.luxoft.com

Strategy

library of classes -> library of functions

www.luxoft.com

Strategy

www.luxoft.com

Iterator

www.luxoft.com

Iterator

Type: behavioral

Definition: Provide a way to access the elements of an aggregate objects equentially without exposing its underlying representation.

www.luxoft.com

Iterator

external iterator -> internal iterator

www.luxoft.com

Iterator

•  collections have internal foreach() •  streams everywhere •  if not - implement Spliterator

www.luxoft.com

Iterator

www.luxoft.com

Builder

www.luxoft.com

Builder

Type: creational

Definition: Separate the construction of a complex object from its representation so that the same construction process can create different representations.

www.luxoft.com

Builder

•  classic runtime builder •  classic reusable builder (a lot of boiler-plate) •  or just use a consumer if applicable

-  no boiler-plate -  reusable (function composition) -  chaining DSL -  consumer has internal control on objet

www.luxoft.com

Builder

say me how -> I will build as you want

www.luxoft.com

Builder

www.luxoft.com

Function composition

f: a -> b g: b -> c h: c -> d

f g h => andThan() ° °

www.luxoft.com

Function composition

f: a -> b g: b -> c h: c -> d

f g h => andThan() ° °

f: a -> Mb g: b -> Mc h: c -> Md

Mb – container for b

www.luxoft.com

Function composition

f: a -> b g: b -> c h: c -> d

f g h => andThan() ° °

f: a -> Mb g: b -> Mc h: c -> Md

f g h => flatMap() ° °

www.luxoft.com

Monad

www.luxoft.com

Monad

Represents (2 and more) states as a unified value in order to compose transformations

[User | Error] -> validate1 -> [User | Error] -> validate2 -> [User | Error ] -> get

User Error

User

of

www.luxoft.com

Monad

•  Puts a value in a computational context

www.luxoft.com

Monad

•  Puts a value in a computational context •  Function composition on steroids

www.luxoft.com

Monad

•  Puts a value in a computational context •  Function composition on steroids •  Programmable semicolon

www.luxoft.com

Monad

•  Puts a value in a computational context •  Function composition on steroids •  Programmable semicolon •  Chainable container

www.luxoft.com

Monad

f: a -> Ma g: a -> Ma h: a -> Ma

f g h => flatMap ° °

Function composition:

f: a -> Mb g: b -> Mc h: c -> Md

www.luxoft.com

Monad

interface Monad<A> {

Monad<A> unit(A a);

Monad<B> flatMap(Function<A, Monad<B>> f);

}

www.luxoft.com

Monad interface Monad<A> {

Monad<A> unit(A a);

Monad<B> flatMap(Function<A, Monad<B>> f);

default Monad<B> map(Function<A, B> f) {

return flatMap(v -> unit(f.apply(v)));

}

}

www.luxoft.com

Monad interface Monad<A> {

Monad<A> unit(A a);

Monad<B> flatMap(Function<A, Monad<B>> f);

default Monad<B> map(Function<A, B> f) {

return flatMap(v -> unit(f.apply(v)));

}

}

Monad composition

Function application

www.luxoft.com

Monad

•  Hide complexity •  Encapsulate implementation details •  Allow composability •  Increase redability •  Reduce code duplication

www.luxoft.com

Already in Java 8

•  Optional •  Stream •  CompleatableFuture

www.luxoft.com

Monad

www.luxoft.com

Visitor

www.luxoft.com

Visitor

Type: behavioral

Definition: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

www.luxoft.com

Visitor

•  Rarely used pattern

•  Can be replaced by pattern matching

•  Reuse general implementation

www.luxoft.com

Visitor

interface Visitor<T> {

T visit(Square element);

T visit(Circle element);

T visit(Rectangle element);

}

def visit(e: Element): T = e match {

case Square => do1();

case Circle => do2();

case Rectangle => do3();

}

www.luxoft.com

Visitor

www.luxoft.com

Paradigm shift:

•  object centric -> function centric

•  function composition reduce complexity

•  data to code -> code to data

•  external -> internal (mechanic incapsulation)

www.luxoft.com

•  functions •  higher order function •  function composition •  partially applied functions •  monads •  pattern matching •  …

New Designers Toolbox

www.luxoft.com

Design Patterns communication tool rather then implementation guide

www.luxoft.com

“In the book we only tell when to apply pattern, but we never talk about when to remove a pattern. Removing a pattern can simplify a system and a simple solution should almost always win. Coming up with a simple solutions is the real challenge.” E.Gamma

www.luxoft.com

•  no silver bullet •  OOP is alive •  GoF “Design Patterns” is still valid •  you just have additional design tools •  almost always trade-off •  use your mind

And remember:

www.luxoft.com

Thanks!!!