java day2016 "reinventing design patterns with java 8"
TRANSCRIPT
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: [email protected]
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!!!