ur domain haz monoids
DESCRIPTION
Domain-Driven Design (DDD) and Functional Programming (FP) have a lot of good things in common: DDD has borrowed many ideas from the FP community, and both share a common inspiration on established formalisms like maths. Even in non functional languages like Java or C#, this combined set of practices from DDD, OO and FP helps craft simple and powerful code that reads well, that is very easy to test, that composes well and that can somehow describe itself. We will have a closer look at some of these ideas, in the context of domain models inspired from real-world projects. From value objects and DSL to abstract algebra creatures like monoids and friends, we will show how all that translates into beautiful code that may influence your coding style!TRANSCRIPT
Ur Domain Haz Monoids?
Cyrille Martraire - @cyriux
"My first encounter with FP concepts was from
DDD"
A matter of Taste
http://rosshirt.blogspot.fr/
The CodeGourmet
(dedicated to @ziobrando)
FP
Passionate developer
PARISSince 1999
@cyriuxCyrille Martraire
Paris Software Craftsmanship Community
http://www.meetup.com/paris-software-craftsmanship/
TDDBDDDDDLegacy
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 bit personal
Adopted 2005Still in love
...
What do DDD & FP have in common?
FP = ?
http://www.jaider.net/archives/609-intro-to-functional-programming/
PURE
No StateNo War
So what do DDD & FP
have in common?
Value Objects................................................................................................. 19
Learn oneand get the other
one for FREE!
DDDFP
(OO)
NICE STYLE
of code
DDD+FP = ?
Example PLZ?
MONOIDZ!
@cyriux
ClosureAssociativity
Neutral Element
only 3 numbers in
programming
0, 1, MANY
Monoid:encapsulate
diversity inside
0, 1, MANY
Neutral Element
Element
Operation
Battle against complexity
Encapsulate details (unit...)
→ simple again
For a given interface I find myself doing often 0, 1, Many
OO FTW!
0, 1, MANY
NullObject
Implementation(s)
Composite
Identity Element
= NullObject
VatCalculation.NONE
Applied often:
→ scalable process
→ can grow to very complex complexity
Example PLZ!
Numbersint+int=int
(3+5)+2=3+(5+2)0
Lists
(.)+(.,.)=(.,.,.) ︎(a ︎)+(b,︎c)=(a ︎, b)+(c) ︎
()
Strings
"hello"+"world""cy"+"ri"+"lle"
""
look simplistic;the key to very
complex behavior
The key to infinite scalability!
The key to infinite incremental computing!
Hadoop x Storm
Composeability
Monoids ☛ reduce
Monoids ☛ domain
Monoids are typical FP
FP: everything is a value
Therefore:Monoids are
values!
VALUEOBJECTS
ImmutableEquals by value
Not Anemic
18°C+ 16°C= 34°C
returns a new instance
Change -> new instance
SIDE-EFFECT -free
FUNCTIONS
Immutability&
Side-effect-free functions!
Value Object
A DDD patternto import FP-ish
values in OO languages
“Functional-First” style
90%“Functional-First” style
Value Objects
(Ok, gut feeling, I did’nt measure)
Money
(25, EUR)+
(30, EUR)=
(55, EUR)
(25, EUR)+
(30, USD)=
exception
Money
amountcurrencyadd(Money): Money
<<ValueObject>>
Cashflows (Payments)
(25, EUR, today)+
(30, EUR, today)=
(55, EUR, today)
(25, EUR, today)+
(30, EUR, next day)=
exception
CashFlow
amountcurrencydate
add(CashFlow):CashFlow
<<ValueObject>>
CLOSURE of
OPERATION
Cashflows Sequences
(10, EUR, 20/03)
(30, EUR, 21/03)
(25, EUR, 21/03)
(12, EUR, 22/03)
(10, EUR, 20/03)
(55, EUR, 21/03)
(12, EUR, 22/03)
+
=
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
ObjectArithmetics
This is how domain experts THINK
about itSAY
SKETCH
Ranges
[1, 3]Union [2, 4]
= [1, 4]
[1, 3]Union [2, 4]
= [1, 4] ][
Predicates
FilterAND Filter
= Filter
FilterAND Filter
= Filter
Always
True
FilterOR
Filter=
Filter
FilterOR
Filter=
FilterAlways
False
Grants
Read, Write, Execute
"most secure wins"
r + w = rw + x = w
Configuration Maps
+
=
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
+
=
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
overw
rite
logic
al OR
min
+
=
Color BLUE
Enable TrueTimeout 30 +
=
Color RED
Enable FalseTimeout 25
Desk FX
Color RED
Enable TrueTimeout 25
Desk FX
Default Desk-specific
overw
rite
logic
al OR
min
Values are monoids too!
+
=
Color BLUE
Enable TrueTimeout 30 +
=
Neutral Element
Color BLUE
Enable TrueTimeout 30
+
=
Color BLUE
Enable TrueTimeout 30 +
=Color BLUE
Enable TrueTimeout 30
Value Objects may be
*BIG* object trees!
(DOM)
Non-Linear Stuff(average, std dev,
K-clustering, barycenters...)
Average + Average = WRONG
Average + Average Not Composeable!
avg = sum / count
avg = sum / count
avg = sum / count
avg = sum / count+
avg = sum / count
avg = sum / count+ +
avg = sum / count
avg = sum / count
avg = sum / count
+
=
+
=
(sum, count)
(sum, count)
(sum, count)
+
=
Average
(sum, sum2, count)
(sum, sum2, count)
(sum, sum2, count)
+
=
Std deviation
Can model as a monoid even non-
linear stuff!
MOARMATHS
PLZ!
Monoid several times...
toString(): Stringunion(MailingList): MailingListintersection(MailingList): MailingListnobody(): MailingListeverybody(): MailingList
MailingList
Space Vectors
average temperature = t1.add(t2) .scale(1/2)
returns a new instance
Change -> new instance
Space Vector
toCelsius(): TemperaturetoFarenheit(): Temperatureadd(Temperature): Temperaturescale(double): Temperature
Temperature
Why is it useful?
(10, EUR, 20/03)
(30, EUR, 21/03)
(25, EUR, 21/03)
(12, EUR, 22/03)
(10, EUR, 20/03)
(55, EUR, 21/03)
(12, EUR, 22/03)
+
=
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
This is how domain experts THINK
about itSAY
SKETCH
DECLARATIVE STYLE
Much less codeMuch less bugs
// without monoidsPaymentsFees(...)PaymentsFeesWithOptions(...)PaymentsFeesWithInsuranceAndOptions(...)PaymentsFeesWithInsurance(...)NoFeesButInsurance(...)...
// with monoidsfees(...) : Paymentsoptions(...) : Paymentsinsurance(...) : Payments
Payments.add(Payments) : Payments
side-effect-free
operation
Very easy to test
input output
Much less stuff to learn
1 interface to rule them all
Cashflow Sequence +
Cashflow Sequence =
Cashflow Sequence
ESTABLISHEDFORMALISMS
Monoid/Vector Spaces/Cyclic Group
LiteratureDocumented
@annotations
@Monoid()intersection(MailingList): MailingList
@NeutralElement("intersection")nobody(): MailingList
MailingList
LIVINGDOCUMENTATION
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
Write code that tells the business
domain stories
@annotations
@Monoid()intersection(MailingList): MailingList
@NeutralElement("intersection")nobody(): MailingList
MailingList
Domain-Specific
@Monoid()overlaping(MailingList): MailingList
@NeutralElement("overlaping")nobody(): MailingList
MailingList
Value Objects have domain-specific
flavors too:
Convention, Policy, Status, Quantity,
Observation...
- Annotate domain-relevant classes
- Custom Doclet to export Excel-formatted glossary of every domain concept
Glossary from Code
Sent directly to end customers
Glossary from Code
SELF-EXPLAINING VALUES
We Want:Traceability of processing
No worry!
Just enrich our types
Just enrich our types
Just enrich our types
label field
Monad-ishNo logging neededEach value stores
its history
http://stuartcook.files.wordpress.com/2010/11/happy-monkey.jpg
In Closing
Invest time:
Learn DDD, and get free FP exposure
A paradox:
FP influence helps craft better Object-
Oriented code!
Monoids are good: Eat Them!
LOOK 4 Ur DOMAIN MONOIDZ!
Also learn other maths structures
Wikipedia is your friend!
DDD+FP=
http://wadler.blogspot.fr/2008/04/functional-programming-is-beautiful.html
Taste-Driven Development
TDD
Questions? Did you try similar things too?
Let’s discuss!
@cyriux
Follow me @cyriux
Slides: slideshare.net/cyriux
Blog: cyrille.martraire.com
In Paris? Join !
Merci