Refactor
your
Specs!
Cyrille Martraire - @cyriux -
what if specs could be
improved?
Specs
Specs
Specs
http://25.media.tumblr.com/tumblr_lus2bi5FAU1qhnnqjo1_500.jpg
Passionate
developer
PARIS
Since 1999
@cyriux
Paris Software
Craftsmanship Community

http://www.meetup.com/paris-software-craftsmanship/
TDD
BDD
DDD
Legacy
Soft ware
Craftsmanship
bar "
g the
aisi n
"R
g c o de
or k in
"W
o ugh"
ot en
is n
Soft ware
Craftsmanship
abou t
h at
W
y we
h e wa
t
e c i f y?
sp
Once upon a
time...
A project...
We Want:

Financial
Calculations
Here are:

The formulas
Case 1
Code It!
(with BDD)
3M
ond on EURIBOR
ate b
en a floating r 5M EUR
Giv
f 1
And a nominal o
15
ate of 2011/06/
And an issue d of 2012/06/14
And an end date UAL calculation period
And an SEMI_ANN
es:
URIBOR 3M evolv
When the E
5% |
2011/09/15 | 3.
|
0% |
2012/03/15 | 4.
|
re:
e cash-flows a0 |
Then th
2300
| 2011/12/13 |
0 |
12/06/14 | 2550
| 20
DONE
double sum = 0;
for (CashFlow cf : cashflows){
double df = 1 + rate * t;
sum += cf.getAmount() / df;
}
return sum;
http://stuartcook.files.wordpress.com/2010/11/happy-monkey.jpg
Case 2
DONE
double sum = 0;
for (CashFlow cf : cashflows){
double df = pow(1 + rate), t);
sum += cf.getAmount() / df;
}
return sum;
Spot the difference
double sum = 0;
for (CashFlow cf : cashflows){
double df = 1 + rate * t;
sum += cf.getAmount() / df;
}
return sum;

double sum = 0;
for (CashFlow cf : cashflows){
double df = pow(1 + rate), t);
sum += cf.getAmount() / df;
}
return sum;
Spot the difference
double sum = 0;
for (CashFlow cf : cashflows){
double df = 1 + rate * t;
sum += cf.getAmount() / df;
}
return sum;

double sum = 0;
for (CashFlow cf : cashflows){
double df = pow(1 + rate), t);
sum += cf.getAmount() / df;
}
return sum;
Duplication?
TDD-ish
Remove
duplication

http://agileinaflash.blogspot.fr/2009/02/red-green-refactor.html
Refactor!
Cases 1 or 2
double sum = 0;
for (CashFlow cf : cashflows){
double df =
sum += cf.getAmount() / df;
}
return sum;

1 + rate * t
pow(1 + rate), t)
Cases 1 or 2
What business sense?
What name?
Ask the experts
Oh, I see what you
mean...
This is the
‘convention for
interests
calculation’
Thx, we can
grow our
Ubiquituous
Language now!
Cool.

...
Next
?

...
What’s its
name?
We call that the
‘coupon’, or just
‘cashflow’
Thx!
Cashflows
...
Putting it
all together
One formula
Many possibilities
...
...
Combinations
cashflow
IR convention

...
...
Combinations
Combinations
Combinations
Discover Domain
in-depth
bon
R ib
C o s t ume
Systematic
bon
R ib
+
C o s t ume
=
te k i t t y
Cu
Combinations
mo de l
A
of the
dom a i n
pattern 1

Systematic
Combination
large variety from a few primitives
4ribbons
+4costumes
4+4 -> 4*4
4+4 -> 4*4
4+4 -> 4*4
Less code
Lessu bugs
o w i n!
Y
Changes in
one place
Testing
Easy Harder
Technically:
- Strategy pattern
applied several times
- A (rigid) domainspecific language
Suggestion by
combination
Suggestion by
combination
i ve
ic t
ed
Pr
el
od
m
Ex t rap

o l a te
Suggestion by
combination
I t ’s v a l id
le
ib
ss
o
p Ye
Im
s, g re at
ide a !
Suggestion by
combination
e
g
n l
le de
l
a o
h m
C e
h
t
Break the model
[Chris Matts]

examples -> model -> more examples
Beware!

t o o Do n’t b e
n’t g o
Do
t h an
e r i c sm a r t e r
ge n
make
Mus t
e nse
e ss s
b us i n

i ne s s
b us
p e o p l e ...)
us t a l i t t le bi t
(o r j

f or f un
o t jus t
N
And now for
some more
patterns...
pattern 2

Different, but
not really
same purpose, same thing
1. Concrete examples
2. visualize

3. Recognize refactoring
opportunities
Plain Text
"On each anniversary date, the bond pays a coupon"
"At the end of each period, the swap pays a cashflow"
Recognize
opportunities
"On each anniversary date, the bond pays a coupon
"At the end of each period, the swap pays a cashflow"

S am

io !?
e n ar
e sc
More visually
bond

$
$

swap

time
time
Equivalentanager
r a f und m
Fo
bond

$
$

swap

time
time
Same purpose
bond

$

e n ar io !
ame s c
S $
swap

time
time
Tip: Focus on one context

≠
≠
=
Systematic in this context

≠
≠
=

Le g a l
o ne y
M

n age me n t
Ma
Systematic in this context
an sp ort
Tr
gu l at io n
Re

≠

= go
Car
S h i pp i n g
Systematic in this context
Dp oDt
ans D r
Tr
u at o n
golunided
ReB
≠exts
Cont

= go
Car
S h i pp i n g
pattern 3

Degenerate
Case
Nothing is just a special case of something
Tax calculation
VAT
VAT on net price
Not Applicable

at io n
a lc ul
C

?
Introduce
Special Case
g is a
o t hi n
Do -N
se of
ial c a
spe c
l at io n
c a lc u
Systematic
VAT
VAT on net price
Not Applicable

at io n
a lc ul
C
Technically:
- Null Object pattern
(Fowler)
pattern 3 bis

Optional
Element
Systematic thanks to an optional element
Workflows
UK/US credit
application

France credit
application

Credit
score
OK?

Credit
score
OK?

Compute
Credit
Limit

Compute
Credit
Limit

References
Check

Record
Outcome

Record
Outcome
Recognize
opportunity
UK/US credit
application

France credit
application

Credit
score
OK?

Credit
score
OK?

Compute
Credit
Limit

References
Check

Record
Outcome

Compute
Credit
Limit

References
Check

Record
Outcome
Systematic
credit application
Credit
score
OK?

Compute
Credit
Limit

[]
References
Check

Record
Outcome

l s te p
io n a
Op t
pattern 3 ter

Manual as special
case of automatic
Systematic thanks to a alternate element
Workflows
Automatic credit
application

Manual credit
application

Credit
score
OK?

Compute
Credit
Limit

References
Check

Record
Outcome

Compute
Credit
Limit

References
Check

Record
Outcome
Systematic

]
[

Compute
Credit
Limit

l s te p
anua
M

References
Check

Record
Outcome
pattern 4

Not my
business
Systematic by moving non-intrinsic logic away
Toys inventory
50x

EU R 1. 50

100x

USD 3. 25

25x

U R 5. 70
M
t a l v a l ue?
To
e nds
"De p

duc t "
e pro
on th
e nds
"De p

duc t "
e pro
on th

EUR
product

qty * price

non-EUR

product

qty * price * fx rate
ccy/EUR

MUR, IQD...

qty * price * fx rate
ccy/USD
* fx rate

except MUR, IQD...

product

USD/EUR
duc t "
e p ro n cy
o n t h u r re
e nds
"De p
c
EUR
product

qty * price

non-EUR

product

qty * price * fx rate
ccy/EUR

MUR, IQD...

qty * price * fx rate
ccy/USD
* fx rate

except MUR, IQD...

product

product

USD/EUR
pe nds
"De

e n cy"
e cur r
on th

EUR
product
non-EUR

product

except HKD, ZAR...

HKD, ZAR...

product

qty * price * currency
conversion
Systematic
qty * price * currency
conversion
r re n cy
Se e C u
(
s i ne s s
io ns b u
o n ve rs
C
h e re )
e s e lse w
r ul
pattern 5

Principles
over rules
Systematic at the underlying principle level
Try it yourself
ar ke t
upe r m
S
r ic i ng
p
K at a
C o de
http://codekata.pragprog.com/
.65
$0
3 for $1

(what if I buy 4, or 5?)

$1.99/pound
(cost for 4 ounces?)

.65
$0
Pricing by quantity
decision tree
1
2
3
4
$0.65
$1.00
$1.30 $1.30 $1.65
+

suggest
buy 3

+

suggest
buy 6

.65
$0
.65
$0

Pr i n c i p le :
t ’s b e s t
" Wh a
f or t he
u s t o me r "
c
.65
$0

Pr i n c i p le :
t ’s b e s t
" Wh a
C o u ld b e
the
f or
e r " i m p le me n te d
c us t om
l i te ra l l y. . .
Technically:
- Declarative code
(brute force)
- Rules engine...
each pattern
=
opportunity to
simplify
each pattern
=
sed
mis
opportunity of
simplification
Traditionally
Specifications

Describe the
system we
want to build
Specifications

Once built,
specs become
documentation
Specifications

Once built,
te
o le
specsbbecome
s
o
documentation
Now we
know better...
User Stories
As a ne w v is i t o r
I w a nt t o re g is te r
I n o rde r t o re c e i ve
s p am
15
p o in t s: 10
Conversations
I w a nt t h is b u tto n
m o re to t h e left
.. .
BDD scenarios
ve n I’m l o g ge d i n
Gi
e Logof f bu t ton
W h e n I c lic k t h
n I’m l o g ge d o f f
The
Perfect for
many cases
Richer
domain,
more
specs!
Equations
Rules
all not be ly
Taxes sh
troactive
hanged re
c
State machines
Workflows
Common situation

+
Gi ve n I’m log ge d in
bu tt on
W he n I click th e Lo go ff
Th en I’m log ge d of f

more details
Often far
from
perfect
Often far
from
perfect
Too much
upfront
One-way
Boring

& Repetitive
So How to

Really
improve this
specs thing?
Refactor your
specs
the w

abou t
t hi n k
ay yo u

Refactor your
specs
The 3 amigos
Just tell me
what to do
No, we ne e d yo u r s k il ls t o
s im p li f y a n d s ug ge s t
a b s t rac t io n s

TDD, refactoring, patterns...
Ju st gi m m e
exa mp le s, I’ ll
reve rse it al l in
TDD
No, we ne e d a t r ue
b us ine s s p e rs p e c t ive

DDD Ubiquitous Language
I ca n on ly
he lp on ce it’s
do ne
No, yo u’re even mo re use fu l
alo ng th e road, wi th yo ur sk ills
on ch allenging ever yt hing

3 amigos & specification workshops
Tester in
India?
2+1 amigos
IRL LOL
I ne ed sp ec s
to de ri ve te st
ca se s
Why no t co lla bo rate du ring th e
wo rk sh op s? We’ll do th e tes t ca ses
at th e same time

Specifications by Example
Why no t co lla bo rate du ring th e
s ce n ar io s
wo rk sh op s? We’ll do th e tes t ca ses
at th e same time

Specifications by Example
Email
Excel
BDD tool
Whatever
My jo b is to
so lve p ro blem s &
te ll w hat to do
"90% of time
BA’s bring
solutions"
- former head of BA’s
Specs as
"Amateur
Design"
Yo ur jo b is to ch al le nge
th e proble m in-dep th

Feature Injection, Impact Mapping
If I do n’t w ri te a
do cu m ent I’m
useles s!
Re la x ! Th e do cume n t is
a lways late to th e p a rt y
Re a l wo r k is h a pp e n ing
in fo rm a ll y, w h ile we ta lk .
An d yo u a ls o h ave to faci li tate
a n d e x p la in th e b usi ne ss
dom a in to e ve r yo ne
Train
the team
new
collabor
e ar

q ue n t
n d f re
ly a

Specs -> Conversations
l l 3 am ig o s
b e t we e n a
e ar

q ue n t
n d f re
ly a

Specs -> conversations
bou t
at a
u t wh
B
h e n?
io n t
n t at
c ume
do
Living documentation
[Gojko Adzic]

m p le s
Exa
n te n t
I
e n ts)
c omm
(Fre e
Living documentation
I n te n t
Living documentation

re te e xam p le s
C onc
Living documentation
Fre e c omme n t s
Living documentation
Visible Workings
[Brian Marick]

o c le t
t om D
C us
p o rt
i me e x
Run t
o rt. . .
e x e xp
L aT
Source code as reference
- Annotate domain-relevant classes

- Custom Doclet to export Excelformatted glossary of every domain
concept
Source code as reference
Sent directly to end customers
Runtime exports
Runtime exports
(1+r)^{frac{t_1 - t_0}{360}}
1+r.frac{t_1 - t_0}{365}
1+rt
(1+r)^{t}

sum_{i=0}^{n}frac{

}{

}
Think critically
Challenge things
Refactor the code
Refactor at the domain
level too
Exploit opportunities
As long as it’s in line with
the business domain
What about you?
- Introduce Just-In-Time
specification workshops with the
3 amigos
- Consider Living Documentation
Questions?
Feedback?
@cyriux
Merci

Refactor your specs! Øredev 2013