Refactor
your
Specs!
Cyrille Martraire - @cyriux -
Specs
Specs
Specs
Passionate
developer
PARIS
Since 1999
@cyriux
Paris Software
Craftsmanship Community
http://www.meetup.com/paris-software-craftsmanship/
TDD
BDD
DDD
Legacy
Software
Craftsmanship
"Raising the bar"
"Working code
is not enough"
Software
Craftsmanship
What about
the way we
specify?
Once upon a
time...
A project...
WeWant:
Financial
Calculations
Hereare:
Theformulas
Case 1
Code It!
(with BDD)
Given a floating rate bond on EURIBOR 3M
And a nominal of 15M EUR
And an issue date of 2011/06/15
And an end date of 2012/06/14
And an SEMI_ANNUAL calculation period
When the EURIBOR 3M evolves:
| 2011/09/15 | 3.5% |
| 2012/03/15 | 4.0% |
Then the cash-flows are:
| 2011/12/13 | 23000 |
| 2012/06/14 | 25500 |
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;
double sum = 0;
for (CashFlow cf : cashflows){
double df = pow(1 + rate), t);
sum += cf.getAmount() / df;
}
return sum;
double sum = 0;
for (CashFlow cf : cashflows){
double df = 1 + rate * t;
sum += cf.getAmount() / df;
}
return sum;
Spot the difference
double sum = 0;
for (CashFlow cf : cashflows){
double df = pow(1 + rate), t);
sum += cf.getAmount() / df;
}
return sum;
double sum = 0;
for (CashFlow cf : cashflows){
double df = 1 + rate * t;
sum += cf.getAmount() / df;
}
return sum;
Spot the difference
Duplication?
TDD-ish
http://agileinaflash.blogspot.fr/2009/02/red-green-refactor.html
Remove
duplication
Refactor!
pow(1 + rate), t)
double sum = 0;
for (CashFlow cf : cashflows){
double df =
sum += cf.getAmount() / df;
}
return sum;
Cases 1 or 2
1 + rate * t
*
Cases 1 or 2
Refactor!
code-level
or
spec-level
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
Ribbon
Costume
Systematic
Ribbon
Costume
+
=
Cute kitty
A model
of the
domain
Combinations
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
Less bugsYou win!
Changes in
one place
Testing
HarderEasy
Technically:
- Strategy pattern
applied several times
- A (rigid) domain-
specific language
Suggestion by
combination
Suggestion by
combination
Predictive
model
Extrapolate
Suggestion by
combination
Impossible
It’s valid
Yes, great
idea!
Suggestion by
combination
Challenge
the model
Break the model
[Chris Matts]
examples -> model -> more examples
Beware!
Don’t go too
generic
Don’t be
smarter than
business
peopleMust make
business sense (or just a little bit...)
Not just for fun
And now for
some more
patterns...
pattern 2
Contextual
Symmetry
same purpose, same thing, locally
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"
Same scenario!?
More visually
bond
swap
time
time
$
$
time
time
$
$
Equivalent
bond
swap
For a fund manager
time
time
$
$
Same purpose
bond
swap
Same scenario!
Tip: Focus on one context
=
≠
≠
Systematic in this context
=
≠
≠
Legal
Money
Management
Systematic in this context
=
≠
Transport
Regulation
Cargo
Shipping
Systematic in this context
=
≠
Transport
Regulation
Cargo
Shipping
DDD
Bounded
Contexts
Domain-
specific!code-level
or spec-level
One Book. Many Views.
Book To Read
Buyable
Catalog
Shopping Cart
Searchable
Search
Billable
Billing
Recommendable
Recommandation
Priceable
Pricing
Shippable
Shipping
Capabilities!
Same capability
Same thing in this context
”A book is a
shippable like any
other”
Like any other shippable:
• Books
• DVDs
• Little toys
87Random stuff?
88
Stuff you can climb on
pattern 3
Degenerate
Case
Nothing is just a special case of something
Tax calculation
VAT
VAT on net price
Not Applicable
Calculation
?
Introduce
Special Case
Do-Nothing is a
special case of
calculation
Systematic
VAT
VAT on net price
Not Applicable
Calculation
Technically:
- Null Object pattern
(Fowler)
Refactoring
patterns
code-level
or spec-level
pattern 3 bis
Optional
Element
Systematic thanks to an optional element
Workflows
Credit
score
OK?
Compute
Credit
Limit
References
Check
Record
Outcome
UK/US credit
application
France credit
application Credit
score
OK?
Compute
Credit
Limit
Record
Outcome
Recognize
opportunity
Credit
score
OK?
Compute
Credit
Limit
References
Check
Record
Outcome
UK/US credit
application
France credit
application
Credit
score
OK?
Compute
Credit
Limit
References
Check
Record
Outcome
Credit
score
OK?
Compute
Credit
Limit
References
Check
Record
Outcome
credit application
[]
Optional step
Systematic
pattern 3 ter
Manual as special
case of automatic
Systematic thanks to a alternate element
Workflows
Credit
score
OK?
Compute
Credit
Limit
References
Check
Record
Outcome
Automatic credit
application
Manual credit
application
Compute
Credit
Limit
References
Check
Record
Outcome
Compute
Credit
Limit
References
Check
Record
Outcome
Manual step
Systematic
[ ]
Of course you could
end up there by
code refactoring…
Refactoring
patterns
code-level
or spec-level
pattern 5
Principles
over rules
Systematic at the underlying principle level
Try it yourself
codekata.com
Supermarket
pricing
Code Kata
$0.65
3 for $1
(what if I buy 4, or 5?)
$1.99/pound
(cost for 4 ounces?)
$0.65
$0.65
1 2 3 4
$0.65 $1.00
$1.65
+
suggest
buy 6
$1.30
+
suggest
buy 3
$1.30
Pricing by quantity
decision tree
$0.65
Principle:
"What’s best
for the
customer"
$0.65
Principle:
"What’s best
for the
customer"
Could be
implemented
literally...
Don’t act as a
HUMAN
COMPILER
Technically:
- Declarative code
(brute force): compute
each case & select
best
- Rules engine...
Declarative
Imperative
code-level
or spec-level
Vs.
each pattern
=
opportunity to
simplify
each pattern
=
opportunity of
simplification
missed
Opportunities don’t
just happen;
Provoke them!
each pattern
=
opportunity to
turn MANY into
ONE
Need to see the
MANY at once
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
DEPTH-FIRST -> FINISH
:(
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
INITIAL DESIGN ON 1 SINGLE CASE
:(
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
BREADTH-FIRST -> EXPLORE
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
BREADTH-FIRST -> EXPLORE
User
Story?
Feature 1 Feature 2 Feature N
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
User Story
Ordering work
A LITTLE UPFRONT THINKING
?
LIKE IN TDD!
Driving the
implementation and
its design by ordering
the tests strategically
- e-commerce: kind of
product sold (book, dvd,
jewelries, vod…)
- finance: asset class
- insurance: health, life,
motor…
Frequent axis of opportunities:
Traditionally
Specifications
Describe the
system we
want to build
Specifications
Once built,
specs become
documentation
Specifications
Once built,
specs become
documentation
obsolete
Now we
know better...
User Stories
As a new visitor
I want to register
In order to receive
spam
points: 10
15
Conversations
I want this button
more to the left
...
BDD scenarios
Given I’m logged in
When I click the Logoff button
Then I’m logged off
Perfect for
many cases
Richer
domain,
more
specs!
Equations
Rules
”Taxes shall not
be changed
retroactively”
State machines
Workflows
Common situation
+
more details
Given I’m logged in
When I click the Logoff button
Then I’m logged off
Often far from perfect
Too much
upfront
One-way
Boring
& Repetitive
So How to
Really
improve this
specs thing?
Refactor your
specs
Refactor your
specs
the way you think about
The 3 amigos
Just tell me
what to do
No, we need your skills to
simplify and suggest
abstractions
TDD, refactoring, patterns...
Just gimme
examples, I’ll
reverse it all in
TDD
No, we need a true
business perspective
DDD Ubiquitous Language
I can only
help once it’s
done
No, you’re even more useful
along the road, with your skills
on challenging everything
3 amigos & specification workshops
Tester in
India?
2+1 amigos
IRL LOL
I need specs
to derive test
cases
Why not collaborate during the
workshops? We’ll do the test cases
at the same time
Specifications by Example
Why not collaborate during the
workshops? We’ll do the test cases
at the same time
Specifications by Example
scenarios
Email
Excel
BDD tool
Whatever
My job is to
solve problems &
tell what to do
Specs as
"Amateur
Design"
Your job is to challenge
the problem in-depth
Feature Injection, Impact Mapping
If I don’t write a
document I’m
useless!
Relax! The document is
always late to the party
Real work is happening
informally, while we talk.
And you also have to facilitate
and explain the business
domain to everyone
Train
the team
new collabo
Specs -> Conversations
early and frequent
between all 3 amigos
Specs -> conversations
early and frequent
But what about
documentation then?
Living documentation
[Gojko Adzic]
Examples
Intent
(Free comments)
Living documentation
Intent
Living documentation
Concrete examples
Living documentation
Free comments
Formulas, Rules, Principle
Living documentation
@aloyer tzatziki
Visible Workings
[Brian Marick]
Custom Doclet
Runtime export
LaTex export...
- Annotate domain-relevant classes
- Custom Doclet to export Excel-
formatted glossary of every domain
concept
Source code as reference
Living Glossary
Sent directly to end customers
Runtime exports
Runtime exports
sum_{i=0}^{n}frac{ }{ }
1+rt
(1+r)^{t}
(1+r)^{frac{t_1 - t_0}{360}}
1+r.frac{t_1 - t_0}{365}
https://leanpub.com/livingdocumentation
BUY MY BOOK!
LIVING DOCUMENTATION
Refactor the code
Refactor at the domain
level too
Exploit opportunities
As long as it’s in line with
the business domain
Provoke opportunities
Explore early enough & order
your work strategically!
Questions?
Feedback?
@cyriux
Merci

Refactor your Specs - 2017 Edition