WHEN FP meets DDD
Good Things Happen
Cyrille Martraire - @cyriux -
http://25.media.tumblr.com/tumblr_lus2bi5FAU1qhnnqjo1_500.jpg
Passionate developer
PARISSince 1999
@cyriuxCyrille Martraire
Paris Software Craftsmanship Community
http://www.meetup.com/paris-software-craftsmanship/
WARNINGThe following show features no spectacular stunt, no live coding, only trivial Java code. You can re-create or re-enact at home with no danger.
A matter of Taste
http://rosshirt.blogspot.fr/
The Code Gourmet
(dedicate to @ziobrando)
"My !rst encounter with FP concepts was from DDD"
DDD?just enough theory
http://www.virtual-genius.com/blog/post/Domain-Driven-Design-Immersion-Course-e28093-Part-5.aspx
Focus on the domain!
Seniors Developers
http://www.thisisio.ie/blog/article/149/hiring_senior_developer
I. Putting the model to work
II. Building blocks (Tactical DDD)
III.Refactoring toward deeper insight
IV. Strategic DDD
Adopted 2005Still in love
What do you think when you hear
about FP?
http://jeremykun.com/2013/02/08/why-there-is-no-hitchhikers-guide-to-mathematics-for-programmers/
http://www.jaider.net/archives/609-intro-to-functional-programming/
PURE
What do DDD & FP have in common?
Value Objects................................................................................................. 19
Learn oneand get the other
one for FREE!
NICE STYLE
of code
Let’s try that
sample practice
(Prag) Dave Thomas
http://codekata.pragprog.com/
Code Kata FTW!
DayMax TemperatureMin TemperatureUnit (C/F)
Please computeDaily min-max spreads
Daily min-max midsMonthly average
...
Compute spread
& console output
DuplicationDuplication
Transaction Script 1
Transaction Script 2
Transaction Script 1
Transaction Script 2≈
Data access
Data access
Presentation Presentation
Domain Domain
Transaction Script 1
Transaction Script 2
Data access
Data access
Presentation Presentation
Domain Domain
Transaction Script 1
Transaction Script 2
≈
Data access
Data access
Presentation Presentation
Domain Domain
Transaction Script 1
Transaction Script 2
≈
=
Data access
Data access
Presentation Presentation
Domain Domain
Transaction Script 1
Transaction Script 2
≈
=
=
Data access
Presentation
Domain Domain
Data access
Presentation
Domain Domain≈
Data access
Presentation
Domain
Data access
Presentation
Domain
Refactoring of similar Transaction Scripts -> layers!
Emergence of a domain layer
Emergence of a domain layer
DDD
Emergence of a domain layer
DDD
Domain layer:"Here we talk about
the domain only"
My hygiene standards in domain layer
• Dependencies– Legacy– Middleware– Frameworks– Database stuff– No logging
null+ TDD, BDD+ Clean Code
Load data
process data
output data
<<side-effect-free>>
Load data
<<side-effect>>
<<side-effect>>
process data
output data
<<side-effect-free>>
Load data
<<side-effect>>
<<side-effect>>
process data
output data
Favor side-effect-free functions in
domain layer
Data access
Presentation
Domain functions
records
list
side-effect-free function
Very easy to test
input output
http://le.compendium.pagesperso-orange.fr/compendium_metrique.htm
expected = expression
Side-effect free service
<<ValueObject
<<ValueObject
<<ValueObject>><<ValueObje
ct<<ValueObject>>
<<Service>><<SPI>><<Service>>
<<API>>
Values in Values out
DuplicationDuplication
Let’s factor it out
Extract a function?
Temperature
valueunitbehavior!
"65°F"
No getter/setter
Immutable
Enum
Immutable Goodnessbugs
keep old statesafe sharing
(concurrency)
Temperature
valueunitbehavior!
<<ValueObject>>
Value Object:equals by "elds
equality
FP: everything is a value
Value Object
A DDD patternto import FP-ish
values in OO languages
“Functional-First” style
“Functional-First” style
• Value Objects (Quantity, Range…) as much as possible
90%“Functional-First” style
Value Objects
(Ok, gut feeling, I did’nt measure)
Methods return same type
toCelsius(): TemperaturetoFarenheit(): Temperature
Temperature
Methods return same type
toCelsius(): TemperaturetoFarenheit(): Temperature
Temperature
double sum = 0;int count = 0;for(Temperature t in temperatures){ sum+= t1.toCelsius().getValue(); count++;}return sum/count;
double sum = 0;int count = 0;for(Temperature t in temperatures){ sum+= t1.toCelsius().getValue(); count++;}return sum/count;
DEMETER VIOLATION
avg = t1.add(t2) .scale(1/2);
returns a new instance
Change -> new instance
Methods manipulate same type
toCelsius(): TemperaturetoFarenheit(): Temperatureadd(Temperature): Temperaturescale(double): Temperature
Temperature
Closure of Operations
Closure of Operations
18°C+ 16°C= 34°C
Temperature sum = max.add(min);
18°C+ 16°C= 34°C
ObjectArithmetics
ObjectArithmetics
...for(...){...}
...for(...){...}
DuplicationDuplication
We can even do better
How do domain experts THINK
about it?
How do domain experts THINK
about it?SAY
SKETCH
Go out and listen to them!
Tell us about your domain
blabla Time Series bla bla...
Yes, let me show you
- =
Max Min Spreads
Introduce a type TimeSeries
TimeSeries spread = max.subtract(min);
<<ValueObject>>
TimeSeries
pointsat(i)add(TimeSeries):TimeSeriessubtract(TimeSeries):TimeSeries
Value Objectagain
Closure of Operations
again
add(TimeSeries):TimeSeriessubtract(TimeSeries):TimeSeries
Declarative styleTimeSeries spread = max.subtract(min);
Temperature sum = max.add(min);
Better style emerging from
refactoring with a focus on the omain
Wrote code with:
Wrote code with:
no naked primitive
Wrote code with:
no naked primitiveno naked collection
Object Calisthenics?
Signal to Noise ratio
http://www.flickr.com/photos/28471130@N07/2666802097
Signal to Noise Ratio
• SNR ≥ 80 %
• Signal (VO): CashFlow.multiply(), CashFlowSequence.add(), .negate(), truncate(), Money.add(), .times(), .opposite(), Fixing, FinancialProduct, BankHolidays, ReferenceData
• Noise: CashFlowBuilder, CompositeEngine, ProductFactory, BankHolidaysDecorator
We Want:Traceability of processing
Just enrich our types
Just enrich our types
Just enrich our types
label "eld
Monad-ishNo logging neededEach value stores
its history
Draw on established formalisms
ObjectArithmetics
=Maths structure
Magma/Monoid/Vector Spaces
Identity Element
= NullObject
Identity Element
= NullObject
VatCalculation.NONE
Wikipedia is your friend!
Invest time:
Learn DDD, and get free FP exposure
A paradox:
FP in!uence helps craft better Object-
Oriented code!
DDD + FPA love story
http://wadler.blogspot.fr/2008/04/functional-programming-is-beautiful.html
Taste-Driven Development
TDD
Questions?
You can also ask me later!
@cyriux