185
WHEN FP meets DDD Good Things Happen Cyrille Martraire - @cyriux -

I T.A.K.E. talk: "When DDD meets FP, good things happen"

Embed Size (px)

Citation preview

WHEN FP meets DDD

Good Things Happen

Cyrille Martraire - @cyriux -

Passionate developer

PARISSince 1999

@cyriuxCyrille Martraire

Paris Software Craftsmanship Community

http://www.meetup.com/paris-software-craftsmanship/

Arolla.fr

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"

a bit personal

DDD+FP = ?

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?

No StateNo War

What do DDD & FP have in common?

Value Objects................................................................................................. 19

Learn oneand get the other

one for FREE!

DDDFP

(OO)

DDDFP

(OO)

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

...

GO

Read !le

Compute spread

& console output

DONE.

NEXT

DONE.

UH-OH!

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

NEXT

= 1/N ∑

Varying units

18°C+ 65°F= ?

DuplicationDuplication

Let’s factor it out

Extract a function?

We can do better

Extract a

TYPE

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

avg = 1 ∑ti n i

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

avg = 1 ∑ti n i

unit-safe

DONE.

...for(...){...}

...for(...){...}

DuplicationDuplication

Zipper?

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...

Time Series?

Yes, let me show you

- =

Max Min Spreads

OK

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);

So far

Domain Layer

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

No worry!

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!

In Closing

Invest time:

Learn DDD, and get free FP exposure

A paradox:

FP in!uence helps craft better Object-

Oriented code!

DDD + FPA love story

Taste-Driven Development

TDD

Questions?

You can also ask me later!

@cyriux

Merci

Merci