SlideShare a Scribd company logo
1 of 60
Download to read offline
by Mario Fusco
mario.fusco@gmail.com
@mariofusco
From object oriented
to functional
domain modeling
ļƒ˜Reassigning a variable
ļƒ˜Modifying a data structure in place
ļƒ˜Setting a field on an object
ļƒ˜Throwing an exception or halting with an error
ļƒ˜Printing to the console
ļƒ˜Reading user input
ļƒ˜Reading from or writing to a file
ļƒ˜Drawing on the screen
A program created using only pure functions
What is a functional program?
No (observable) side effects allowed like:
Functional programming is a restriction on how we write
programs, but not on what they can do
}
}
avoidable
deferrable
OOP makes code understandable
by encapsulating moving parts
FP makes code understandable
by minimizing moving parts
- Michael Feathers
OOP vs FP
Why Immutability?
āž¢ Immutable objects are often easier to use.
Compare java.util.Calendar (mutable)
with java.time.LocalDate (immutable)
āž¢ Implementing an immutable object is often
easier, as there is less that can go wrong
āž¢ Immutable objects reduce the number of
possible interactions between different
parts of the program
āž¢ Immutable objects can be safely shared
between multiple threads
A quick premise
It is not only black or white ...
Object
Oriented
Programming
Functional
Programming
A quick premise
It is not only black or white ...
ā€¦ there are (at least)
50 shades of gray in the middle
Object
Oriented
Programming
Functional
Programming
The OOP/FP dualism - OOP
public class Bird { }
public class Cat {
private Bird catch;
private boolean full;
public void capture(Bird bird) {
catch = bird;
}
public void eat() {
full = true;
catch = null;
}
}
Cat cat = new Cat();
Bird bird = new Bird();
cat.capture(bird);
cat.eat();
The story
The OOP/FP dualism - FP
public class Bird { }
public class Cat {
public CatWithCatch capture(Bird bird) { return new CatWithCatch(bird); }
}
public class CatWithCatch {
private final Bird catch;
public CatWithCatch(Bird bird) { catch = bird; }
public FullCat eat() { return new FullCat(); }
}
public class FullCat { }
BiFunction<Cat, Bird, FullCat> story =
((BiFunction<Cat, Bird, CatWithCatch>)Cat::capture)
.andThen(CatWithCatch::eat);
FullCat fullCat = story.apply( new Cat(), new Bird() );
Immutability
Emphasis on verbs
instead of names
No need to test internal state: correctness enforced by the compiler
More expressive
use of type system
From Object to Function centric
BiFunction<Cat, Bird, CatWithCatch> capture =
(cat, bird) -> cat.capture(bird);
Function<CatWithCatch, FullCat> eat =
CatWithCatch::eat;
BiFunction<Cat, Bird, FullCat> story = capture.andThen(eat);
Functions
compose
better than
objects
A composable functional API
public class API {
public static Cart buy(List<Item> items) { ... }
public static Order order(Cart cart) { ... }
public static Delivery deliver(Order order) { ... }
}
Function<Delivery, List<Item>> oneClickBuy =
((Function<Cart, List<Item>>) API::buy)
.andThen(API::order)
.andThen(API::deliver);
Delivery d = oneClickBuy.apply(asList(book, watch, phone));
public static <T> void sort(List<T> list,
Comparator<? super T> c)
Essence of Functional Programming
Data and behaviors are the same thing!
Data
Behaviors
Collections.sort(persons,
(p1, p2) -> p1.getAge() ā€“ p2.getAge())
Higher-order functions
Are they so mind-blowing?
ā€¦ but one of the most influent sw engineering
book is almost completely dedicated to them
Command
Template Method
Functions are more general and higher level abstractions
Factory
Strategy
public interface Converter {
double convert(double value);
}
A strategy pattern Converter
public abstract class AbstractConverter implements Converter {
public double convert(double value) {
return value * getConversionRate();
}
public abstract double getConversionRate();
}
public class Mi2KmConverter extends AbstractConverter {
public double getConversionRate() { return 1.609; }
}
public class Ou2GrConverter extends AbstractConverter {
public double getConversionRate() { return 28.345; }
}
public List<Double> convertValues(List<Double> values,
Converter converter) {
List<Double> convertedValues = new ArrayList<Double>();
for (double value : values) {
convertedValues.add(converter.convert(value));
}
return convertedValues;
}
Using the Converter
List<Double> values = Arrays.asList(10, 20, 50);
List<Double> convertedDistances =
convertValues(values, new Mi2KmConverter());
List<Double> convertedWeights =
convertValues(values, new Ou2GrConverter());
A functional Converter
public class Converter implements
ExtendedBiFunction<Double, Double, Double> {
@Override
public Double apply(Double conversionRate, Double value) {
return conversionRate * value;
}
}
@FunctionalInterface
public interface ExtendedBiFunction<T, U, R> extends
BiFunction<T, U, R> {
default Function<U, R> curry1(T t) {
return u -> apply(t, u);
}
default Function<T, R> curry2(U u) {
return t -> apply(t, u);
}
}
Currying
Converter converter = new Converter();
double tenMilesInKm = converter.apply(1.609, 10.0);
Function<Double, Double> mi2kmConverter = converter.curry1(1.609);
double tenMilesInKm = mi2kmConverter.apply(10.0);
Converter
value
rate
result
Mi2km
Convertervalue
rate=1.609
result
curry1
List<Double> values = Stream.of(10, 20, 50)
.map(mi2kmConverter)
.collect(toList())
Function Composition
Celsius ā†’ Fahrenheit : F = C * 9/5 + 32
Converter
value
rate=9/5 andThen
n -> n+32
result
Celsius2FarenheitConverter
Function<Double, Double> c2fConverter =
new Converter().curry1(9.0/5)
.andThen(n -> n + 32);
More Function Composition
@FunctionalInterface
public interface ExtendedBiFunction<T, U, R> extends
BiFunction<T, U, R> {
default <V> ExtendedBiFunction<V, U, R>
compose1(Function<? super V, ? extends T> before) {
return (v, u) -> apply(before.apply(v), u);
}
default <V> ExtendedBiFunction<T, V, R>
compose2(Function<? super V, ? extends U> before) {
return (t, v) -> apply(t, before.apply(v));
}
}
default <V> Function<V, R>
compose(Function<? super V, ? extends T> before) {
return (V v) -> apply(before.apply(v));
}
More Function Composition
Fahrenheit ā†’ Celsius : C = (F - 32) * 5/9
Converter
rate=5/9
value
n -> n-32
result
Farenheit2CelsiusConverter
Function<Double, Double> f2cConverter =
new Converter().compose2((Double n) -> n - 32)
.curry1(5.0/9);
Functions are building blocks to create other functions
compose2
public class SalaryCalculator {
public double plusAllowance(double d) { return d * 1.2; }
public double plusBonus(double d) { return d * 1.1; }
public double plusTax(double d) { return d * 0.7; }
public double plusSurcharge(double d) { return d * 0.9; }
public double calculate(double basic, boolean... bs) {
double salary = basic;
if (bs[0]) salary = plusAllowance(salary);
if (bs[1]) salary = plusBonus(salary);
if (bs[2]) salary = plusTax(salary);
if (bs[3]) salary = plusSurcharge(salary);
return salary;
}
}
A Salary Calculator
double basicBobSalary = ...;
double netBobSalary =
new SalaryCalculator().calculate( basicBobSalary,
false, // allowance
true, // bonus
true, // tax
false // surcharge
);
Using the Salary Calculator
How can I
remember the
right sequence?
public class SalaryCalculatorBuilder extends SalaryCalculator {
private boolean hasAllowance;
private boolean hasBonus;
private boolean hasTax;
private boolean hasSurcharge;
public SalaryCalculatorFactory withAllowance() {
hasAllowance = true;
return this;
}
// ... more withX() methods
public double calculate(double basic) {
return calculate( basic, hasAllowance, hasBonus,
hasTax, hasSurcharge );
}
}
A Salary Calculator Builder
double basicBobSalary = ...;
double netBobSalary = new SalaryCalculatorBuilder()
.withBonus()
.withTax()
.calculate( basicBobSalary );
Using the Salary Calculator Factory
Better,
but what if I have to
add another function?
public final class SalaryRules {
private SalaryRules() { }
public static double allowance(double d) { return d * 1.2; }
public static double bonus(double d) { return d * 1.1; }
public static double tax(double d) { return d * 0.7; }
public static double surcharge(double d) { return d * 0.9; }
}
Isolating Salary Rules
public class SalaryCalculator {
private final List<Function<Double, Double>> fs =
new ArrayList<>();
public SalaryCalculator with(Function<Double, Double> f) {
fs.add(f);
return this;
}
public double calculate(double basic) {
return fs.stream()
.reduce( Function.identity(), Function::andThen )
.apply( basic );
}
}
A Functional Salary Calculator
double basicBobSalary = ...;
double netBobSalary = new SalaryCalculator()
.with( SalaryRules::bonus )
.with( SalaryRules::tax )
.calculate( basicBobSalary );
Using the Functional Salary Calculator
āž¢ No need of any special
builder to improve readability
double basicBobSalary = ...;
double netBobSalary = new SalaryCalculator()
.with( SalaryRules::bonus )
.with( SalaryRules::tax )
.with( s -> s * 0.95 ) // regional tax
.calculate( basicBobSalary );
Using the Functional Salary Calculator
āž¢ No need of any special
builder to improve readability
āž¢ Extensibility comes for free
public class SalaryCalculator {
private final Function<Double, Double> calc;
public SalaryCalculator() { this( Function::identity() ); }
private SalaryCalculator(Function<Double, Double> calc) {
this.calc = calc;
}
public SalaryCalculator with(Function<Double, Double> f) {
return new SalaryCalculator( calc.andThen(f) );
}
public double calculate(double basic) {
return calc.apply( basic );
}
}
A (better) Functional Salary Calculator
JĪ›VĪ›SLĪ›NG
A functional Library for Java 8
Immutable Collections
Pattern Matching
Failure Handling
Tuple3<Person, Account, Building>
final A result = Try.of(() -> bunchOfWork())
.recover(x -> Match
.caze((Exception_1 e) -> ...)
.caze((Exception_2 e) -> ...)
.caze((Exception_n e) -> ...)
.apply(x))
.orElse(other);
Let's have a coffee break ...
public class Cafe {
public Coffee buyCoffee(CreditCard cc) {
Coffee cup = new Coffee();
cc.charge( cup.getPrice() );
return cup;
}
public List<Coffee> buyCoffees(CreditCard cc, int n) {
return Stream.generate( () -> buyCoffee( cc ) )
.limit( n )
.collect( toList() );
}
}
Side-effect
How can we test this without
contacting the bank or using a mock?
How can reuse that method to
buy more coffees without
charging the card multiple times?
ā€¦ but please a side-effect free one
import javaslang.Tuple2;
import javaslang.collection.Stream;
public class Cafe {
public Tuple2<Coffee, Charge> buyCoffee(CreditCard cc) {
Coffee cup = new Coffee();
return new Tuple2<>(cup, new Charge(cc, cup.getPrice()));
}
public Tuple2<List<Coffee>, Charge> buyCoffees(CreditCard cc, int n) {
Tuple2<Stream<Coffee>, Stream<Charge>> purchases =
Stream.gen( () -> buyCoffee( cc ) )
.subsequence( 0, n )
.unzip( identity() );
return new Tuple2<>( purchases._1.toJavaList(),
purchases._2.foldLeft( new Charge( cc, 0 ),
Charge::add) );
}
}
public Charge add(Charge other) {
if (cc == other.cc)
return new Charge(cc, amount + other.amount);
else
throw new RuntimeException(
"Can't combine charges to different cards");
}
Error handling with Exceptions?
āž¢
Often abused, especially for flow
control
āž¢
Checked Exceptions harm API
extensibility/modificability
āž¢
They also plays very badly with
lambdas syntax
āž¢
Not composable: in presence of
multiple errors only the first one is
reported
āž¢
In the end just a GLORIFIED
MULTILEVEL GOTO
Error handling
The functional alternatives
Either<Exception, Value>
āž¢
The functional way of returning a value which can actually be one
of two values: the error/exception (Left) or the correct value (Right)
Validation<List<Exception>, Value>
āž¢
Composable: can accumulate multiple errors
Try<Value>
āž¢
Signal that the required computation may eventually fail
A OOP BankAccount ...
public class Balance {
final BigDecimal amount;
public Balance( BigDecimal amount ) { this.amount = amount; }
}
public class Account {
private final String owner;
private final String number;
private Balance balance = new Balance(BigDecimal.ZERO);
public Account( String owner, String number ) {
this.owner = owner;
this.number = number;
}
public void credit(BigDecimal value) {
balance = new Balance( balance.amount.add( value ) );
}
public void debit(BigDecimal value) throws InsufficientBalanceException {
if (balance.amount.compareTo( value ) < 0)
throw new InsufficientBalanceException();
balance = new Balance( balance.amount.subtract( value ) );
}
}
Mutability
Error handling
using Exception
ā€¦ and how we can use it
Account a = new Account("Alice", "123");
Account b = new Account("Bob", "456");
Account c = new Account("Charlie", "789");
List<Account> unpaid = new ArrayList<>();
for (Account account : Arrays.asList(a, b, c)) {
try {
account.debit( new BigDecimal( 100.00 ) );
} catch (InsufficientBalanceException e) {
unpaid.add(account);
}
}
List<Account> unpaid = new ArrayList<>();
Stream.of(a, b, c).forEach( account -> {
try {
account.debit( new BigDecimal( 100.00 ) );
} catch (InsufficientBalanceException e) {
unpaid.add(account);
}
} );
Mutation of enclosing scope
Cannot use a parallel Stream
Ugly syntax
Error handling with Try monad
public interface Try<A> {
<B> Try<B> map(Function<A, B> f);
<B> Try<B> flatMap(Function<A, Try<B>> f);
boolean isFailure();
}
public Success<A> implements Try<A> {
private final A value;
public Success(A value) { this.value = value; }
public boolean isFailure() { return false; }
public <B> Try<B> map(Function<A, B> f) {
return new Success<>(f.apply(value));
}
public <B> Try<B> flatMap(Function<A, Try<B>> f) {
return f.apply(value);
}
}
public Failure<A> implements Try<T> {
private final Object error;
public Failure(Object error) { this.error = error; }
public boolean isFailure() { return false; }
public <B> Try<B> map(Function<A, B> f) { return (Failure<B>)this; }
public <B> Try<B> flatMap(Function<A, Try<B>> f) { return (Failure<B>)this; }
}
map defines monad's policy
for function application
flatMap defines monad's policy
for monads composition
A functional BankAccount ...
public class Account {
private final String owner;
private final String number;
private final Balance balance;
public Account( String owner, String number, Balance balance ) {
this.owner = owner;
this.number = number;
this.balance = balance;
}
public Account credit(BigDecimal value) {
return new Account( owner, number,
new Balance( balance.amount.add( value ) ) );
}
public Try<Account> debit(BigDecimal value) {
if (balance.amount.compareTo( value ) < 0)
return new Failure<>( new InsufficientBalanceError() );
return new Success<>(
new Account( owner, number,
new Balance( balance.amount.subtract( value ) ) ) );
}
}
Immutable
Error handling
without Exceptions
ā€¦ and how we can use it
Account a = new Account("Alice", "123");
Account b = new Account("Bob", "456");
Account c = new Account("Charlie", "789");
List<Account> unpaid =
Stream.of( a, b, c )
.map( account ->
new Tuple2<>( account,
account.debit( new BigDecimal( 100.00 ) ) ) )
.filter( t -> t._2.isFailure() )
.map( t -> t._1 )
.collect( toList() );
List<Account> unpaid =
Stream.of( a, b, c )
.filter( account ->
account.debit( new BigDecimal( 100.00 ) )
.isFailure() )
.collect( toList() );
From Methods to Functions
public class BankService {
public static Try<Account> open(String owner, String number,
BigDecimal balance) {
if (initialBalance.compareTo( BigDecimal.ZERO ) < 0)
return new Failure<>( new InsufficientBalanceError() );
return new Success<>( new Account( owner, number,
new Balance( balance ) ) );
}
public static Account credit(Account account, BigDecimal value) {
return new Account( account.owner, account.number,
new Balance( account.balance.amount.add( value ) ) );
}
public static Try<Account> debit(Account account, BigDecimal value) {
if (account.balance.amount.compareTo( value ) < 0)
return new Failure<>( new InsufficientBalanceError() );
return new Success<>(
new Account( account.owner, account.number,
new Balance( account.balance.amount.subtract( value ) ) ) );
}
}
Decoupling state and behavior
import static BankService.*
Try<Account> account =
open( "Alice", "123", new BigDecimal( 100.00 ) )
.map( acc -> credit( acc, new BigDecimal( 200.00 ) ) )
.map( acc -> credit( acc, new BigDecimal( 300.00 ) ) )
.flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ) );
The object-oriented paradigm couples state and behavior
Functional programming decouples them
ā€¦ but I need a BankConnection!
What about dependency injection?
A naĆÆve solution
public class BankService {
public static Try<Account> open(String owner, String number,
BigDecimal balance, BankConnection bankConnection) {
...
}
public static Account credit(Account account, BigDecimal value,
BankConnection bankConnection) {
...
}
public static Try<Account> debit(Account account, BigDecimal value,
BankConnection bankConnection) {
...
}
}
BankConnection bconn = new BankConnection();
Try<Account> account =
open( "Alice", "123", new BigDecimal( 100.00 ), bconn )
.map( acc -> credit( acc, new BigDecimal( 200.00 ), bconn ) )
.map( acc -> credit( acc, new BigDecimal( 300.00 ), bconn ) )
.flatMap( acc -> debit( acc, new BigDecimal( 400.00 ), bconn ) );
Necessary to create the
BankConnection in advance ...
ā€¦ and pass it to all methods
Making it lazy
public class BankService {
public static Function<BankConnection, Try<Account>>
open(String owner, String number, BigDecimal balance) {
return (BankConnection bankConnection) -> ...
}
public static Function<BankConnection, Account>
credit(Account account, BigDecimal value) {
return (BankConnection bankConnection) -> ...
}
public static Function<BankConnection, Try<Account>>
debit(Account account, BigDecimal value) {
return (BankConnection bankConnection) -> ...
}
}
Function<BankConnection, Try<Account>> f =
(BankConnection conn) ->
open( "Alice", "123", new BigDecimal( 100.00 ) )
.apply( conn )
.map( acc -> credit( acc, new BigDecimal( 200.00 ) ).apply( conn ) )
.map( acc -> credit( acc, new BigDecimal( 300.00 ) ).apply( conn ) )
.flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ).apply( conn ) );
Try<Account> account = f.apply( new BankConnection() );
Introducing the Reader monad ...
public class Reader<R, A> {
private final Function<R, A> run;
public Reader( Function<R, A> run ) {
this.run = run;
}
public <B> Reader<R, B> map(Function<A, B> f) {
return new Reader<>((R r) -> f.apply( apply( r ) ));
}
public <B> Reader<R, B> flatMap(Function<A, Reader<R, B>> f) {
return new Reader<>((R r) -> f.apply( apply( r ) ).apply( r ));
}
public A apply(R r) {
return run.apply( r );
}
}
The reader monad provides a computation environment
ā€¦ and combining it with Try
public class TryReader<R, A> {
private final Function<R, Try<A>> run;
public TryReader( Function<R, Try<A>> run ) {
this.run = run;
}
public <B> TryReader<R, B> map(Function<A, B> f) {
return new TryReader<R, B>((R r) -> apply( r )
.map( a -> f.apply( a ) ));
}
public <B> TryReader<R, B> mapReader(Function<A, Reader<R, B>> f) {
return new TryReader<R, B>((R r) -> apply( r )
.map( a -> f.apply( a ).apply( r ) ));
}
public <B> TryReader<R, B> flatMap(Function<A, TryReader<R, B>> f) {
return new TryReader<R, B>((R r) -> apply( r )
.flatMap( a -> f.apply( a ).apply( r ) ));
}
public Try<A> apply(R r) {
return run.apply( r );
}
}
A more user-friendly API
public class BankService {
public static TryReader<BankConnection, Account>
open(String owner, String number, BigDecimal balance) {
return new TryReader<>( (BankConnection bankConnection) -> ... )
}
public static Reader<BankConnection, Account>
credit(Account account, BigDecimal value) {
return new Reader<>( (BankConnection bankConnection) -> ... )
}
public static TryReader<BankConnection, Account>
debit(Account account, BigDecimal value) {
return new TryReader<>( (BankConnection bankConnection) -> ... )
}
}
TryReader<BankConnection, Account> reader =
open( "Alice", "123", new BigDecimal( 100.00 ) )
.mapReader( acc -> credit( acc, new BigDecimal( 200.00 ) ) )
.mapReader( acc -> credit( acc, new BigDecimal( 300.00 ) ) )
.flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ) );
Try<Account> account = reader.apply( new BankConnection() );
Wrap up
Toward a functional domain model
API design is an iterative process
Strive for immutability
private final Object obj;
Confine side-effects
Avoid using exceptions for error handling
Say it with types
Tuple3<
Function<
BankConnection,
Try<Account>
>,
Optional<Address>,
Future<
List<Withdrawal>
>
>
Use anemic object
Put domain logic in pure functions
FP allows better
Reusability & Composability
OOP
FP
=
Throw away your
GoF copy ...
ā€¦ and learn some
functional patterns
Suggested readings
Mario Fusco
Red Hat ā€“ Senior Software Engineer
mario.fusco@gmail.com
twitter: @mariofusco
Q A
Thanks ā€¦ Questions?

More Related Content

What's hot

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 WorkshopMario Fusco
Ā 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
Ā 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
Ā 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and StreamsVenkata Naga Ravi
Ā 
Functional Programming
Functional ProgrammingFunctional Programming
Functional ProgrammingRyan Riley
Ā 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
Ā 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
Ā 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda ExpressionsScott Leberknight
Ā 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8RichardWarburton
Ā 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8Richard Walker
Ā 
Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Abid Kohistani
Ā 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Scott Wlaschin
Ā 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Scott Wlaschin
Ā 
Polymorphism
PolymorphismPolymorphism
PolymorphismKumar Gaurav
Ā 
Clean code slide
Clean code slideClean code slide
Clean code slideAnh Huan Miu
Ā 

What's hot (20)

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
Ā 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
Ā 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
Ā 
Java 8 Lambda and Streams
Java 8 Lambda and StreamsJava 8 Lambda and Streams
Java 8 Lambda and Streams
Ā 
Java interface
Java interfaceJava interface
Java interface
Ā 
Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
Ā 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
Ā 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
Ā 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
Ā 
Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
Ā 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8
Ā 
Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#
Ā 
Applicative style programming
Applicative style programmingApplicative style programming
Applicative style programming
Ā 
Clean Code
Clean CodeClean Code
Clean Code
Ā 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)
Ā 
Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013Domain Driven Design with the F# type System -- NDC London 2013
Domain Driven Design with the F# type System -- NDC London 2013
Ā 
Clean code
Clean codeClean code
Clean code
Ā 
Polymorphism
PolymorphismPolymorphism
Polymorphism
Ā 
Clean code slide
Clean code slideClean code slide
Clean code slide
Ā 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Ā 

Viewers also liked

Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
Ā 
Introduction to Kafka with Spring Integration
Introduction to Kafka with Spring IntegrationIntroduction to Kafka with Spring Integration
Introduction to Kafka with Spring IntegrationBorislav Markov
Ā 
Introduction To Functional Reactive Programming Poznan
Introduction To Functional Reactive Programming PoznanIntroduction To Functional Reactive Programming Poznan
Introduction To Functional Reactive Programming PoznanEliasz Sawicki
Ā 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudBen Wilcock
Ā 
Spring integration with the Java DSL
Spring integration with the Java DSLSpring integration with the Java DSL
Spring integration with the Java DSLBen Wilcock
Ā 
Microservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingMicroservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingBen Wilcock
Ā 
Integration Patterns and Anti-Patterns for Microservices Architectures
Integration Patterns and Anti-Patterns for Microservices ArchitecturesIntegration Patterns and Anti-Patterns for Microservices Architectures
Integration Patterns and Anti-Patterns for Microservices ArchitecturesApcera
Ā 
Scaling wix with microservices architecture devoxx London 2015
Scaling wix with microservices architecture devoxx London 2015Scaling wix with microservices architecture devoxx London 2015
Scaling wix with microservices architecture devoxx London 2015Aviran Mordo
Ā 

Viewers also liked (8)

Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Ā 
Introduction to Kafka with Spring Integration
Introduction to Kafka with Spring IntegrationIntroduction to Kafka with Spring Integration
Introduction to Kafka with Spring Integration
Ā 
Introduction To Functional Reactive Programming Poznan
Introduction To Functional Reactive Programming PoznanIntroduction To Functional Reactive Programming Poznan
Introduction To Functional Reactive Programming Poznan
Ā 
Microservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloudMicroservices - java ee vs spring boot and spring cloud
Microservices - java ee vs spring boot and spring cloud
Ā 
Spring integration with the Java DSL
Spring integration with the Java DSLSpring integration with the Java DSL
Spring integration with the Java DSL
Ā 
Microservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event SourcingMicroservice Architecture with CQRS and Event Sourcing
Microservice Architecture with CQRS and Event Sourcing
Ā 
Integration Patterns and Anti-Patterns for Microservices Architectures
Integration Patterns and Anti-Patterns for Microservices ArchitecturesIntegration Patterns and Anti-Patterns for Microservices Architectures
Integration Patterns and Anti-Patterns for Microservices Architectures
Ā 
Scaling wix with microservices architecture devoxx London 2015
Scaling wix with microservices architecture devoxx London 2015Scaling wix with microservices architecture devoxx London 2015
Scaling wix with microservices architecture devoxx London 2015
Ā 

Similar to From object oriented to functional domain modeling

Functional programming 101
Functional programming 101Functional programming 101
Functional programming 101Maneesh Chaturvedi
Ā 
Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++ppd1961
Ā 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)RichardWarburton
Ā 
Functional Programming with Javascript
Functional Programming with JavascriptFunctional Programming with Javascript
Functional Programming with JavascriptDeepankar Chopra
Ā 
power point presentation on object oriented programming functions concepts
power point presentation on object oriented programming functions conceptspower point presentation on object oriented programming functions concepts
power point presentation on object oriented programming functions conceptsbhargavi804095
Ā 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09Daniel Bryant
Ā 
Unit-III.pptx
Unit-III.pptxUnit-III.pptx
Unit-III.pptxMehul Desai
Ā 
Functionincprogram
FunctionincprogramFunctionincprogram
FunctionincprogramSampath Kumar
Ā 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.pptssuser823678
Ā 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.pptssuser2076d9
Ā 
CH.4FUNCTIONS IN C_FYBSC(CS).pptx
CH.4FUNCTIONS IN C_FYBSC(CS).pptxCH.4FUNCTIONS IN C_FYBSC(CS).pptx
CH.4FUNCTIONS IN C_FYBSC(CS).pptxSangeetaBorde3
Ā 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1rohassanie
Ā 
Pragmatic Functional Refactoring with Java 8
Pragmatic Functional Refactoring with Java 8Pragmatic Functional Refactoring with Java 8
Pragmatic Functional Refactoring with Java 8Codemotion
Ā 

Similar to From object oriented to functional domain modeling (20)

Functional programming 101
Functional programming 101Functional programming 101
Functional programming 101
Ā 
Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++
Ā 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
Ā 
Refactoring
RefactoringRefactoring
Refactoring
Ā 
Functional Programming with Javascript
Functional Programming with JavascriptFunctional Programming with Javascript
Functional Programming with Javascript
Ā 
Function
Function Function
Function
Ā 
C++ Functions.ppt
C++ Functions.pptC++ Functions.ppt
C++ Functions.ppt
Ā 
power point presentation on object oriented programming functions concepts
power point presentation on object oriented programming functions conceptspower point presentation on object oriented programming functions concepts
power point presentation on object oriented programming functions concepts
Ā 
Refactoring
RefactoringRefactoring
Refactoring
Ā 
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09L2 Web App Development Guest Lecture At University of Surrey 20/11/09
L2 Web App Development Guest Lecture At University of Surrey 20/11/09
Ā 
Unit-III.pptx
Unit-III.pptxUnit-III.pptx
Unit-III.pptx
Ā 
Function C++
Function C++ Function C++
Function C++
Ā 
Gwt and Xtend
Gwt and XtendGwt and Xtend
Gwt and Xtend
Ā 
Functionincprogram
FunctionincprogramFunctionincprogram
Functionincprogram
Ā 
functions
functionsfunctions
functions
Ā 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
Ā 
function_v1.ppt
function_v1.pptfunction_v1.ppt
function_v1.ppt
Ā 
CH.4FUNCTIONS IN C_FYBSC(CS).pptx
CH.4FUNCTIONS IN C_FYBSC(CS).pptxCH.4FUNCTIONS IN C_FYBSC(CS).pptx
CH.4FUNCTIONS IN C_FYBSC(CS).pptx
Ā 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
Ā 
Pragmatic Functional Refactoring with Java 8
Pragmatic Functional Refactoring with Java 8Pragmatic Functional Refactoring with Java 8
Pragmatic Functional Refactoring with Java 8
Ā 

More from Mario Fusco

Kogito: cloud native business automation
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automationMario Fusco
Ā 
How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...Mario Fusco
Ā 
OOP and FP
OOP and FPOOP and FP
OOP and FPMario Fusco
Ā 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep diveMario Fusco
Ā 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerMario Fusco
Ā 
Comparing different concurrency models on the JVM
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVMMario Fusco
Ā 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
Ā 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingMario Fusco
Ā 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageMario Fusco
Ā 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing DroolsMario Fusco
Ā 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardMario Fusco
Ā 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife SpringMario Fusco
Ā 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdajMario Fusco
Ā 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
Ā 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
Ā 

More from Mario Fusco (16)

Kogito: cloud native business automation
Kogito: cloud native business automationKogito: cloud native business automation
Kogito: cloud native business automation
Ā 
How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...How and why I turned my old Java projects into a first-class serverless compo...
How and why I turned my old Java projects into a first-class serverless compo...
Ā 
OOP and FP
OOP and FPOOP and FP
OOP and FP
Ā 
Drools 6 deep dive
Drools 6 deep diveDrools 6 deep dive
Drools 6 deep dive
Ā 
OOP and FP - Become a Better Programmer
OOP and FP - Become a Better ProgrammerOOP and FP - Become a Better Programmer
OOP and FP - Become a Better Programmer
Ā 
Comparing different concurrency models on the JVM
Comparing different concurrency models on the JVMComparing different concurrency models on the JVM
Comparing different concurrency models on the JVM
Ā 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
Ā 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
Ā 
Real world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same languageReal world DSL - making technical and business people speaking the same language
Real world DSL - making technical and business people speaking the same language
Ā 
Introducing Drools
Introducing DroolsIntroducing Drools
Introducing Drools
Ā 
Java 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forwardJava 7, 8 & 9 - Moving the language forward
Java 7, 8 & 9 - Moving the language forward
Ā 
Hammurabi
HammurabiHammurabi
Hammurabi
Ā 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
Ā 
No more loops with lambdaj
No more loops with lambdajNo more loops with lambdaj
No more loops with lambdaj
Ā 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Ā 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Ā 

Recently uploaded

Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
Ā 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
Ā 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
Ā 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
Ā 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
Ā 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
Ā 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
Ā 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
Ā 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
Ā 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
Ā 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
Ā 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto GonzƔlez Trastoy
Ā 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
Ā 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfWilly Marroquin (WillyDevNET)
Ā 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
Ā 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...OnePlan Solutions
Ā 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
Ā 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
Ā 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
Ā 

Recently uploaded (20)

Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
Ā 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
Ā 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
Ā 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
Ā 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Ā 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
Ā 
Call Girls In Mukherjee Nagar šŸ“± 9999965857 šŸ¤© Delhi šŸ«¦ HOT AND SEXY VVIP šŸŽ SE...
Call Girls In Mukherjee Nagar šŸ“±  9999965857  šŸ¤© Delhi šŸ«¦ HOT AND SEXY VVIP šŸŽ SE...Call Girls In Mukherjee Nagar šŸ“±  9999965857  šŸ¤© Delhi šŸ«¦ HOT AND SEXY VVIP šŸŽ SE...
Call Girls In Mukherjee Nagar šŸ“± 9999965857 šŸ¤© Delhi šŸ«¦ HOT AND SEXY VVIP šŸŽ SE...
Ā 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
Ā 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
Ā 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Ā 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
Ā 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
Ā 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Ā 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Ā 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
Ā 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
Ā 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlanā€™s ...
Ā 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
Ā 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
Ā 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
Ā 

From object oriented to functional domain modeling

  • 1. by Mario Fusco mario.fusco@gmail.com @mariofusco From object oriented to functional domain modeling
  • 2. ļƒ˜Reassigning a variable ļƒ˜Modifying a data structure in place ļƒ˜Setting a field on an object ļƒ˜Throwing an exception or halting with an error ļƒ˜Printing to the console ļƒ˜Reading user input ļƒ˜Reading from or writing to a file ļƒ˜Drawing on the screen A program created using only pure functions What is a functional program? No (observable) side effects allowed like: Functional programming is a restriction on how we write programs, but not on what they can do } } avoidable deferrable
  • 3. OOP makes code understandable by encapsulating moving parts FP makes code understandable by minimizing moving parts - Michael Feathers OOP vs FP
  • 4. Why Immutability? āž¢ Immutable objects are often easier to use. Compare java.util.Calendar (mutable) with java.time.LocalDate (immutable) āž¢ Implementing an immutable object is often easier, as there is less that can go wrong āž¢ Immutable objects reduce the number of possible interactions between different parts of the program āž¢ Immutable objects can be safely shared between multiple threads
  • 5. A quick premise It is not only black or white ... Object Oriented Programming Functional Programming
  • 6. A quick premise It is not only black or white ... ā€¦ there are (at least) 50 shades of gray in the middle Object Oriented Programming Functional Programming
  • 7. The OOP/FP dualism - OOP public class Bird { } public class Cat { private Bird catch; private boolean full; public void capture(Bird bird) { catch = bird; } public void eat() { full = true; catch = null; } } Cat cat = new Cat(); Bird bird = new Bird(); cat.capture(bird); cat.eat(); The story
  • 8. The OOP/FP dualism - FP public class Bird { } public class Cat { public CatWithCatch capture(Bird bird) { return new CatWithCatch(bird); } } public class CatWithCatch { private final Bird catch; public CatWithCatch(Bird bird) { catch = bird; } public FullCat eat() { return new FullCat(); } } public class FullCat { } BiFunction<Cat, Bird, FullCat> story = ((BiFunction<Cat, Bird, CatWithCatch>)Cat::capture) .andThen(CatWithCatch::eat); FullCat fullCat = story.apply( new Cat(), new Bird() ); Immutability Emphasis on verbs instead of names No need to test internal state: correctness enforced by the compiler More expressive use of type system
  • 9. From Object to Function centric BiFunction<Cat, Bird, CatWithCatch> capture = (cat, bird) -> cat.capture(bird); Function<CatWithCatch, FullCat> eat = CatWithCatch::eat; BiFunction<Cat, Bird, FullCat> story = capture.andThen(eat); Functions compose better than objects
  • 10. A composable functional API public class API { public static Cart buy(List<Item> items) { ... } public static Order order(Cart cart) { ... } public static Delivery deliver(Order order) { ... } } Function<Delivery, List<Item>> oneClickBuy = ((Function<Cart, List<Item>>) API::buy) .andThen(API::order) .andThen(API::deliver); Delivery d = oneClickBuy.apply(asList(book, watch, phone));
  • 11. public static <T> void sort(List<T> list, Comparator<? super T> c) Essence of Functional Programming Data and behaviors are the same thing! Data Behaviors Collections.sort(persons, (p1, p2) -> p1.getAge() ā€“ p2.getAge())
  • 12. Higher-order functions Are they so mind-blowing? ā€¦ but one of the most influent sw engineering book is almost completely dedicated to them
  • 13. Command Template Method Functions are more general and higher level abstractions Factory Strategy
  • 14. public interface Converter { double convert(double value); } A strategy pattern Converter public abstract class AbstractConverter implements Converter { public double convert(double value) { return value * getConversionRate(); } public abstract double getConversionRate(); } public class Mi2KmConverter extends AbstractConverter { public double getConversionRate() { return 1.609; } } public class Ou2GrConverter extends AbstractConverter { public double getConversionRate() { return 28.345; } }
  • 15. public List<Double> convertValues(List<Double> values, Converter converter) { List<Double> convertedValues = new ArrayList<Double>(); for (double value : values) { convertedValues.add(converter.convert(value)); } return convertedValues; } Using the Converter List<Double> values = Arrays.asList(10, 20, 50); List<Double> convertedDistances = convertValues(values, new Mi2KmConverter()); List<Double> convertedWeights = convertValues(values, new Ou2GrConverter());
  • 16. A functional Converter public class Converter implements ExtendedBiFunction<Double, Double, Double> { @Override public Double apply(Double conversionRate, Double value) { return conversionRate * value; } } @FunctionalInterface public interface ExtendedBiFunction<T, U, R> extends BiFunction<T, U, R> { default Function<U, R> curry1(T t) { return u -> apply(t, u); } default Function<T, R> curry2(U u) { return t -> apply(t, u); } }
  • 17. Currying Converter converter = new Converter(); double tenMilesInKm = converter.apply(1.609, 10.0); Function<Double, Double> mi2kmConverter = converter.curry1(1.609); double tenMilesInKm = mi2kmConverter.apply(10.0); Converter value rate result Mi2km Convertervalue rate=1.609 result curry1 List<Double> values = Stream.of(10, 20, 50) .map(mi2kmConverter) .collect(toList())
  • 18. Function Composition Celsius ā†’ Fahrenheit : F = C * 9/5 + 32 Converter value rate=9/5 andThen n -> n+32 result Celsius2FarenheitConverter Function<Double, Double> c2fConverter = new Converter().curry1(9.0/5) .andThen(n -> n + 32);
  • 19. More Function Composition @FunctionalInterface public interface ExtendedBiFunction<T, U, R> extends BiFunction<T, U, R> { default <V> ExtendedBiFunction<V, U, R> compose1(Function<? super V, ? extends T> before) { return (v, u) -> apply(before.apply(v), u); } default <V> ExtendedBiFunction<T, V, R> compose2(Function<? super V, ? extends U> before) { return (t, v) -> apply(t, before.apply(v)); } } default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { return (V v) -> apply(before.apply(v)); }
  • 20. More Function Composition Fahrenheit ā†’ Celsius : C = (F - 32) * 5/9 Converter rate=5/9 value n -> n-32 result Farenheit2CelsiusConverter Function<Double, Double> f2cConverter = new Converter().compose2((Double n) -> n - 32) .curry1(5.0/9); Functions are building blocks to create other functions compose2
  • 21. public class SalaryCalculator { public double plusAllowance(double d) { return d * 1.2; } public double plusBonus(double d) { return d * 1.1; } public double plusTax(double d) { return d * 0.7; } public double plusSurcharge(double d) { return d * 0.9; } public double calculate(double basic, boolean... bs) { double salary = basic; if (bs[0]) salary = plusAllowance(salary); if (bs[1]) salary = plusBonus(salary); if (bs[2]) salary = plusTax(salary); if (bs[3]) salary = plusSurcharge(salary); return salary; } } A Salary Calculator
  • 22. double basicBobSalary = ...; double netBobSalary = new SalaryCalculator().calculate( basicBobSalary, false, // allowance true, // bonus true, // tax false // surcharge ); Using the Salary Calculator How can I remember the right sequence?
  • 23. public class SalaryCalculatorBuilder extends SalaryCalculator { private boolean hasAllowance; private boolean hasBonus; private boolean hasTax; private boolean hasSurcharge; public SalaryCalculatorFactory withAllowance() { hasAllowance = true; return this; } // ... more withX() methods public double calculate(double basic) { return calculate( basic, hasAllowance, hasBonus, hasTax, hasSurcharge ); } } A Salary Calculator Builder
  • 24. double basicBobSalary = ...; double netBobSalary = new SalaryCalculatorBuilder() .withBonus() .withTax() .calculate( basicBobSalary ); Using the Salary Calculator Factory Better, but what if I have to add another function?
  • 25. public final class SalaryRules { private SalaryRules() { } public static double allowance(double d) { return d * 1.2; } public static double bonus(double d) { return d * 1.1; } public static double tax(double d) { return d * 0.7; } public static double surcharge(double d) { return d * 0.9; } } Isolating Salary Rules
  • 26. public class SalaryCalculator { private final List<Function<Double, Double>> fs = new ArrayList<>(); public SalaryCalculator with(Function<Double, Double> f) { fs.add(f); return this; } public double calculate(double basic) { return fs.stream() .reduce( Function.identity(), Function::andThen ) .apply( basic ); } } A Functional Salary Calculator
  • 27. double basicBobSalary = ...; double netBobSalary = new SalaryCalculator() .with( SalaryRules::bonus ) .with( SalaryRules::tax ) .calculate( basicBobSalary ); Using the Functional Salary Calculator āž¢ No need of any special builder to improve readability
  • 28. double basicBobSalary = ...; double netBobSalary = new SalaryCalculator() .with( SalaryRules::bonus ) .with( SalaryRules::tax ) .with( s -> s * 0.95 ) // regional tax .calculate( basicBobSalary ); Using the Functional Salary Calculator āž¢ No need of any special builder to improve readability āž¢ Extensibility comes for free
  • 29. public class SalaryCalculator { private final Function<Double, Double> calc; public SalaryCalculator() { this( Function::identity() ); } private SalaryCalculator(Function<Double, Double> calc) { this.calc = calc; } public SalaryCalculator with(Function<Double, Double> f) { return new SalaryCalculator( calc.andThen(f) ); } public double calculate(double basic) { return calc.apply( basic ); } } A (better) Functional Salary Calculator
  • 30. JĪ›VĪ›SLĪ›NG A functional Library for Java 8 Immutable Collections Pattern Matching Failure Handling Tuple3<Person, Account, Building> final A result = Try.of(() -> bunchOfWork()) .recover(x -> Match .caze((Exception_1 e) -> ...) .caze((Exception_2 e) -> ...) .caze((Exception_n e) -> ...) .apply(x)) .orElse(other);
  • 31. Let's have a coffee break ... public class Cafe { public Coffee buyCoffee(CreditCard cc) { Coffee cup = new Coffee(); cc.charge( cup.getPrice() ); return cup; } public List<Coffee> buyCoffees(CreditCard cc, int n) { return Stream.generate( () -> buyCoffee( cc ) ) .limit( n ) .collect( toList() ); } } Side-effect How can we test this without contacting the bank or using a mock? How can reuse that method to buy more coffees without charging the card multiple times?
  • 32. ā€¦ but please a side-effect free one import javaslang.Tuple2; import javaslang.collection.Stream; public class Cafe { public Tuple2<Coffee, Charge> buyCoffee(CreditCard cc) { Coffee cup = new Coffee(); return new Tuple2<>(cup, new Charge(cc, cup.getPrice())); } public Tuple2<List<Coffee>, Charge> buyCoffees(CreditCard cc, int n) { Tuple2<Stream<Coffee>, Stream<Charge>> purchases = Stream.gen( () -> buyCoffee( cc ) ) .subsequence( 0, n ) .unzip( identity() ); return new Tuple2<>( purchases._1.toJavaList(), purchases._2.foldLeft( new Charge( cc, 0 ), Charge::add) ); } } public Charge add(Charge other) { if (cc == other.cc) return new Charge(cc, amount + other.amount); else throw new RuntimeException( "Can't combine charges to different cards"); }
  • 33. Error handling with Exceptions? āž¢ Often abused, especially for flow control āž¢ Checked Exceptions harm API extensibility/modificability āž¢ They also plays very badly with lambdas syntax āž¢ Not composable: in presence of multiple errors only the first one is reported āž¢ In the end just a GLORIFIED MULTILEVEL GOTO
  • 34. Error handling The functional alternatives Either<Exception, Value> āž¢ The functional way of returning a value which can actually be one of two values: the error/exception (Left) or the correct value (Right) Validation<List<Exception>, Value> āž¢ Composable: can accumulate multiple errors Try<Value> āž¢ Signal that the required computation may eventually fail
  • 35. A OOP BankAccount ... public class Balance { final BigDecimal amount; public Balance( BigDecimal amount ) { this.amount = amount; } } public class Account { private final String owner; private final String number; private Balance balance = new Balance(BigDecimal.ZERO); public Account( String owner, String number ) { this.owner = owner; this.number = number; } public void credit(BigDecimal value) { balance = new Balance( balance.amount.add( value ) ); } public void debit(BigDecimal value) throws InsufficientBalanceException { if (balance.amount.compareTo( value ) < 0) throw new InsufficientBalanceException(); balance = new Balance( balance.amount.subtract( value ) ); } } Mutability Error handling using Exception
  • 36. ā€¦ and how we can use it Account a = new Account("Alice", "123"); Account b = new Account("Bob", "456"); Account c = new Account("Charlie", "789"); List<Account> unpaid = new ArrayList<>(); for (Account account : Arrays.asList(a, b, c)) { try { account.debit( new BigDecimal( 100.00 ) ); } catch (InsufficientBalanceException e) { unpaid.add(account); } } List<Account> unpaid = new ArrayList<>(); Stream.of(a, b, c).forEach( account -> { try { account.debit( new BigDecimal( 100.00 ) ); } catch (InsufficientBalanceException e) { unpaid.add(account); } } ); Mutation of enclosing scope Cannot use a parallel Stream Ugly syntax
  • 37. Error handling with Try monad public interface Try<A> { <B> Try<B> map(Function<A, B> f); <B> Try<B> flatMap(Function<A, Try<B>> f); boolean isFailure(); } public Success<A> implements Try<A> { private final A value; public Success(A value) { this.value = value; } public boolean isFailure() { return false; } public <B> Try<B> map(Function<A, B> f) { return new Success<>(f.apply(value)); } public <B> Try<B> flatMap(Function<A, Try<B>> f) { return f.apply(value); } } public Failure<A> implements Try<T> { private final Object error; public Failure(Object error) { this.error = error; } public boolean isFailure() { return false; } public <B> Try<B> map(Function<A, B> f) { return (Failure<B>)this; } public <B> Try<B> flatMap(Function<A, Try<B>> f) { return (Failure<B>)this; } } map defines monad's policy for function application flatMap defines monad's policy for monads composition
  • 38. A functional BankAccount ... public class Account { private final String owner; private final String number; private final Balance balance; public Account( String owner, String number, Balance balance ) { this.owner = owner; this.number = number; this.balance = balance; } public Account credit(BigDecimal value) { return new Account( owner, number, new Balance( balance.amount.add( value ) ) ); } public Try<Account> debit(BigDecimal value) { if (balance.amount.compareTo( value ) < 0) return new Failure<>( new InsufficientBalanceError() ); return new Success<>( new Account( owner, number, new Balance( balance.amount.subtract( value ) ) ) ); } } Immutable Error handling without Exceptions
  • 39. ā€¦ and how we can use it Account a = new Account("Alice", "123"); Account b = new Account("Bob", "456"); Account c = new Account("Charlie", "789"); List<Account> unpaid = Stream.of( a, b, c ) .map( account -> new Tuple2<>( account, account.debit( new BigDecimal( 100.00 ) ) ) ) .filter( t -> t._2.isFailure() ) .map( t -> t._1 ) .collect( toList() ); List<Account> unpaid = Stream.of( a, b, c ) .filter( account -> account.debit( new BigDecimal( 100.00 ) ) .isFailure() ) .collect( toList() );
  • 40. From Methods to Functions public class BankService { public static Try<Account> open(String owner, String number, BigDecimal balance) { if (initialBalance.compareTo( BigDecimal.ZERO ) < 0) return new Failure<>( new InsufficientBalanceError() ); return new Success<>( new Account( owner, number, new Balance( balance ) ) ); } public static Account credit(Account account, BigDecimal value) { return new Account( account.owner, account.number, new Balance( account.balance.amount.add( value ) ) ); } public static Try<Account> debit(Account account, BigDecimal value) { if (account.balance.amount.compareTo( value ) < 0) return new Failure<>( new InsufficientBalanceError() ); return new Success<>( new Account( account.owner, account.number, new Balance( account.balance.amount.subtract( value ) ) ) ); } }
  • 41. Decoupling state and behavior import static BankService.* Try<Account> account = open( "Alice", "123", new BigDecimal( 100.00 ) ) .map( acc -> credit( acc, new BigDecimal( 200.00 ) ) ) .map( acc -> credit( acc, new BigDecimal( 300.00 ) ) ) .flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ) ); The object-oriented paradigm couples state and behavior Functional programming decouples them
  • 42. ā€¦ but I need a BankConnection! What about dependency injection?
  • 43. A naĆÆve solution public class BankService { public static Try<Account> open(String owner, String number, BigDecimal balance, BankConnection bankConnection) { ... } public static Account credit(Account account, BigDecimal value, BankConnection bankConnection) { ... } public static Try<Account> debit(Account account, BigDecimal value, BankConnection bankConnection) { ... } } BankConnection bconn = new BankConnection(); Try<Account> account = open( "Alice", "123", new BigDecimal( 100.00 ), bconn ) .map( acc -> credit( acc, new BigDecimal( 200.00 ), bconn ) ) .map( acc -> credit( acc, new BigDecimal( 300.00 ), bconn ) ) .flatMap( acc -> debit( acc, new BigDecimal( 400.00 ), bconn ) ); Necessary to create the BankConnection in advance ... ā€¦ and pass it to all methods
  • 44. Making it lazy public class BankService { public static Function<BankConnection, Try<Account>> open(String owner, String number, BigDecimal balance) { return (BankConnection bankConnection) -> ... } public static Function<BankConnection, Account> credit(Account account, BigDecimal value) { return (BankConnection bankConnection) -> ... } public static Function<BankConnection, Try<Account>> debit(Account account, BigDecimal value) { return (BankConnection bankConnection) -> ... } } Function<BankConnection, Try<Account>> f = (BankConnection conn) -> open( "Alice", "123", new BigDecimal( 100.00 ) ) .apply( conn ) .map( acc -> credit( acc, new BigDecimal( 200.00 ) ).apply( conn ) ) .map( acc -> credit( acc, new BigDecimal( 300.00 ) ).apply( conn ) ) .flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ).apply( conn ) ); Try<Account> account = f.apply( new BankConnection() );
  • 45. Introducing the Reader monad ... public class Reader<R, A> { private final Function<R, A> run; public Reader( Function<R, A> run ) { this.run = run; } public <B> Reader<R, B> map(Function<A, B> f) { return new Reader<>((R r) -> f.apply( apply( r ) )); } public <B> Reader<R, B> flatMap(Function<A, Reader<R, B>> f) { return new Reader<>((R r) -> f.apply( apply( r ) ).apply( r )); } public A apply(R r) { return run.apply( r ); } } The reader monad provides a computation environment
  • 46. ā€¦ and combining it with Try public class TryReader<R, A> { private final Function<R, Try<A>> run; public TryReader( Function<R, Try<A>> run ) { this.run = run; } public <B> TryReader<R, B> map(Function<A, B> f) { return new TryReader<R, B>((R r) -> apply( r ) .map( a -> f.apply( a ) )); } public <B> TryReader<R, B> mapReader(Function<A, Reader<R, B>> f) { return new TryReader<R, B>((R r) -> apply( r ) .map( a -> f.apply( a ).apply( r ) )); } public <B> TryReader<R, B> flatMap(Function<A, TryReader<R, B>> f) { return new TryReader<R, B>((R r) -> apply( r ) .flatMap( a -> f.apply( a ).apply( r ) )); } public Try<A> apply(R r) { return run.apply( r ); } }
  • 47. A more user-friendly API public class BankService { public static TryReader<BankConnection, Account> open(String owner, String number, BigDecimal balance) { return new TryReader<>( (BankConnection bankConnection) -> ... ) } public static Reader<BankConnection, Account> credit(Account account, BigDecimal value) { return new Reader<>( (BankConnection bankConnection) -> ... ) } public static TryReader<BankConnection, Account> debit(Account account, BigDecimal value) { return new TryReader<>( (BankConnection bankConnection) -> ... ) } } TryReader<BankConnection, Account> reader = open( "Alice", "123", new BigDecimal( 100.00 ) ) .mapReader( acc -> credit( acc, new BigDecimal( 200.00 ) ) ) .mapReader( acc -> credit( acc, new BigDecimal( 300.00 ) ) ) .flatMap( acc -> debit( acc, new BigDecimal( 400.00 ) ) ); Try<Account> account = reader.apply( new BankConnection() );
  • 48. Wrap up Toward a functional domain model
  • 49. API design is an iterative process
  • 50. Strive for immutability private final Object obj;
  • 52. Avoid using exceptions for error handling
  • 53. Say it with types Tuple3< Function< BankConnection, Try<Account> >, Optional<Address>, Future< List<Withdrawal> > >
  • 55. Put domain logic in pure functions
  • 56. FP allows better Reusability & Composability OOP FP =
  • 58. ā€¦ and learn some functional patterns
  • 60. Mario Fusco Red Hat ā€“ Senior Software Engineer mario.fusco@gmail.com twitter: @mariofusco Q A Thanks ā€¦ Questions?