Refactor your specs! Øredev 2013

182
Refactor your Specs! Cyrille Martraire - @cyriux -

description

Watch the video online: http://vimeo.com/79181633 Even in an agile world, specifications often go too far and describe solutions with too much details; all these premature decisions constraint the implementation and remove opportunities. There is a remedy: refactoring the specs, even before refactoring the code. In the TDD cycle, refactoring is the art of restructuring the code to make it simpler, without changing its behavior at runtime. A key part of refactoring is to recognize and extract duplications. Refactoring is very useful at the code level, and it is even more powerful when applied during business analysis or functional architecture. We will show how the practice of refactoring directly "at the business domain level" can simplify the problem, and therefore the resulting implementation code, by orders of magnitude. This means much less code to write, to test and to maintain, and much less defects as a result. We will introduce 5 patterns on how to refactor at the business-domain level, such as "Make It Systematic" and "Degenerate Case". We will also explain some limits and the required mindset. This approach of refactoring has been used on several real-world projects and is derived in particular from DDD and from Specification by Example.

Transcript of Refactor your specs! Øredev 2013

Page 1: Refactor your specs! Øredev 2013

Refactor your

Specs!Cyrille Martraire - @cyriux -

Page 2: Refactor your specs! Øredev 2013

what if specs could be improved?

Page 3: Refactor your specs! Øredev 2013

Specs

Page 4: Refactor your specs! Øredev 2013

Specs

Page 5: Refactor your specs! Øredev 2013

Specs

Page 7: Refactor your specs! Øredev 2013

Passionate developer

PARISSince 1999

@cyriux

Page 8: Refactor your specs! Øredev 2013

Paris Software Craftsmanship Community

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

Page 9: Refactor your specs! Øredev 2013

TDDBDDDDDLegacy

Page 10: Refactor your specs! Øredev 2013

Software Craftsmanship

"Raising the bar"

"Working code is not enough"

Page 11: Refactor your specs! Øredev 2013

Software Craftsmanship

What about the way we

specify?

Page 12: Refactor your specs! Øredev 2013

Once upon a time...

Page 13: Refactor your specs! Øredev 2013

A project...

Page 14: Refactor your specs! Øredev 2013

We Want:

Financial Calculations

Page 15: Refactor your specs! Øredev 2013

Here are:

The formulas

Page 16: Refactor your specs! Øredev 2013

Case 1

Page 17: Refactor your specs! Øredev 2013

Code It!

Page 18: Refactor your specs! Øredev 2013

(with BDD)Given a floating r

ate 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 perio

d

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 |

Page 19: Refactor your specs! Øredev 2013

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

Page 21: Refactor your specs! Øredev 2013

Case 2

Page 22: Refactor your specs! Øredev 2013

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

Page 23: Refactor your specs! Øredev 2013
Page 24: Refactor your specs! Øredev 2013

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

Page 25: Refactor your specs! Øredev 2013

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

Page 26: Refactor your specs! Øredev 2013

Duplication?

Page 27: Refactor your specs! Øredev 2013

TDD-ish

http://agileinaflash.blogspot.fr/2009/02/red-green-refactor.html

Remove duplication

Page 28: Refactor your specs! Øredev 2013

Refactor!

Page 29: Refactor your specs! Øredev 2013

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

Page 30: Refactor your specs! Øredev 2013

Cases 1 or 2

Page 31: Refactor your specs! Øredev 2013

What business sense?What name?

Page 32: Refactor your specs! Øredev 2013

Ask the experts

Page 33: Refactor your specs! Øredev 2013

Oh, I see what you mean...

Page 34: Refactor your specs! Øredev 2013

This is the ‘convention for

interests calculation’

Page 35: Refactor your specs! Øredev 2013

Thx, we can grow our

Ubiquituous Language now!

Page 36: Refactor your specs! Øredev 2013

Cool.

...

Page 37: Refactor your specs! Øredev 2013

Next

...

?

Page 38: Refactor your specs! Øredev 2013

What’s its name?

Page 39: Refactor your specs! Øredev 2013

We call that the ‘coupon’, or just

‘cashflow’

Page 40: Refactor your specs! Øredev 2013

Thx!

Page 41: Refactor your specs! Øredev 2013

...

Cashflows

Page 42: Refactor your specs! Øredev 2013

Putting it all together

Page 43: Refactor your specs! Øredev 2013

One formulaMany possibilities

...

...

Page 44: Refactor your specs! Øredev 2013

Combinations

...

cashflow ...IR convention

Page 45: Refactor your specs! Øredev 2013

Combinations

Page 46: Refactor your specs! Øredev 2013

Combinations

Page 47: Refactor your specs! Øredev 2013

Combinations

Page 48: Refactor your specs! Øredev 2013

Discover Domainin-depth

RibbonCostume

Page 49: Refactor your specs! Øredev 2013

SystematicRibbon

Costume+=

Cute kitty

Page 50: Refactor your specs! Øredev 2013

A model of the domain

Combinations

Page 51: Refactor your specs! Øredev 2013

pattern 1

SystematicCombination

large variety from a few primitives

Page 52: Refactor your specs! Øredev 2013

4ribbons

+4costumes

Page 53: Refactor your specs! Øredev 2013
Page 54: Refactor your specs! Øredev 2013
Page 55: Refactor your specs! Øredev 2013
Page 56: Refactor your specs! Øredev 2013
Page 57: Refactor your specs! Øredev 2013
Page 58: Refactor your specs! Øredev 2013
Page 59: Refactor your specs! Øredev 2013
Page 60: Refactor your specs! Øredev 2013

4+4 -> 4*4

Page 61: Refactor your specs! Øredev 2013

4+4 -> 4*4

Page 62: Refactor your specs! Øredev 2013

4+4 -> 4*4Less codeLess bugsYou win!

Page 63: Refactor your specs! Øredev 2013

Changes in one place

Page 64: Refactor your specs! Øredev 2013

Testing

HarderEasy

Page 65: Refactor your specs! Øredev 2013

Technically:

- Strategy pattern applied several times- A (rigid) domain-specific language

Page 66: Refactor your specs! Øredev 2013

Suggestion by combination

Page 67: Refactor your specs! Øredev 2013

Suggestion by combination

Predictive model

Extrapolate

Page 68: Refactor your specs! Øredev 2013

Suggestion by combination

ImpossibleIt’s valid

Yes, great idea!

Page 69: Refactor your specs! Øredev 2013

Suggestion by combination

Challenge

the model

Page 70: Refactor your specs! Øredev 2013

Break the model[Chris Matts]

examples -> model -> more examples

Page 71: Refactor your specs! Øredev 2013

Beware!Don’t go too

genericDon’t be

smarter than business

peopleMust make business sense (or just a little bit...)

Not just for fun

Page 72: Refactor your specs! Øredev 2013

And now for some more patterns...

Page 73: Refactor your specs! Øredev 2013

pattern 2

Different, but not really

same purpose, same thing

Page 74: Refactor your specs! Øredev 2013

1. Concrete examples2. visualize3. Recognize refactoring

opportunities

Page 75: Refactor your specs! Øredev 2013

Plain Text"On each anniversary date, the bond pays a coupon""At the end of each period, the swap pays a cashflow"

Page 76: Refactor your specs! Øredev 2013

Recognize opportunities

"On each anniversary date, the bond pays a coupon"At the end of each period, the swap pays a cashflow"

Same scenario!?

Page 77: Refactor your specs! Øredev 2013

More visuallybond

swap

time

time

$

$

Page 78: Refactor your specs! Øredev 2013

time

time

$

$

Equivalentbond

swap

For a fund manager

Page 79: Refactor your specs! Øredev 2013

time

time

$

$

Same purposebond

swap

Same scenario!

Page 80: Refactor your specs! Øredev 2013

Tip: Focus on one context

=

≠≠

Page 81: Refactor your specs! Øredev 2013

Systematic in this context

=

≠≠

Legal

MoneyManagement

Page 82: Refactor your specs! Øredev 2013

Systematic in this context

=≠

Transport Regulation

Cargo Shipping

Page 83: Refactor your specs! Øredev 2013

Systematic in this context

=≠

Transport Regulation

Cargo Shipping

DDD Bounded Contexts

Page 84: Refactor your specs! Øredev 2013

pattern 3

Degenerate Case

Nothing is just a special case of something

Page 85: Refactor your specs! Øredev 2013

Tax calculation

VAT

VAT on net price

Not Applicable

Calculation

?

Page 86: Refactor your specs! Øredev 2013

Introduce Special CaseDo-Nothing is a special case of

calculation

Page 87: Refactor your specs! Øredev 2013

SystematicVAT

VAT on net price

Not Applicable

Calculation

Page 88: Refactor your specs! Øredev 2013

Technically:

- Null Object pattern (Fowler)

Page 89: Refactor your specs! Øredev 2013

pattern 3 bis

Optional Element

Systematic thanks to an optional element

Page 90: Refactor your specs! Øredev 2013

WorkflowsCredit score OK?

Compute Credit Limit

References Check

Record Outcome

UK/US credit application

France credit application Credit

score OK?

Compute Credit Limit

Record Outcome

Page 91: Refactor your specs! Øredev 2013

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

Page 92: Refactor your specs! Øredev 2013

Credit score OK?

Compute Credit Limit

References Check

Record Outcome

credit application []Optional step

Systematic

Page 93: Refactor your specs! Øredev 2013

pattern 3 ter

Manual as special case of automatic

Systematic thanks to a alternate element

Page 94: Refactor your specs! Øredev 2013

WorkflowsCredit score OK?

Compute Credit Limit

References Check

Record Outcome

Automatic credit application

Manual credit application

Compute Credit Limit

References Check

Record Outcome

Page 95: Refactor your specs! Øredev 2013

Compute Credit Limit

References Check

Record Outcome

Manual step

Systematic

[ ]

Page 96: Refactor your specs! Øredev 2013

pattern 4

Not my business

Systematic by moving non-intrinsic logic away

Page 97: Refactor your specs! Øredev 2013

Toys inventory50x

100x

25x

EUR 1.50

USD 3.25

MUR 5.70

Total value?

Page 98: Refactor your specs! Øredev 2013

"Depends on the product"

Page 99: Refactor your specs! Øredev 2013

EURnon-EUR

MUR, IQD...

qty * price

qty * price * fx rate

qty * price * fx rate * fx rate

ccy/EUR

ccy/USD

USD/EUR

"Depends on the product"

product

productexcept MUR, IQD...

product

Page 100: Refactor your specs! Øredev 2013

EURnon-EUR

MUR, IQD...

qty * price

qty * price * fx rate

qty * price * fx rate * fx rate

ccy/EUR

ccy/USD

USD/EUR

"Depends on the product"

product

productexcept MUR, IQD...

product

product

currency

Page 101: Refactor your specs! Øredev 2013

EURnon-EUR

HKD, ZAR...

qty * price

"Depends on the currency"

product

productexcept HKD, ZAR...

product

* currency conversion

Page 102: Refactor your specs! Øredev 2013

qty * price * currency conversion

Systematic

(See Currency

Conversions business

rules elsewhere)

Page 103: Refactor your specs! Øredev 2013

pattern 5

Principlesover rules

Systematic at the underlying principle level

Page 104: Refactor your specs! Øredev 2013

Try it yourself

http://codekata.pragprog.com/

Supermarket pricing

Code Kata

Page 105: Refactor your specs! Øredev 2013

$0.65

Page 106: Refactor your specs! Øredev 2013

3 for $1 (what if I buy 4, or 5?)

$1.99/pound (cost for 4 ounces?)

$0.65

Page 107: Refactor your specs! Øredev 2013

$0.651 2 3 4

$0.65 $1.00

$1.65 +

suggest buy 6

$1.30 +

suggest buy 3

$1.30

Pricing by quantitydecision tree

Page 108: Refactor your specs! Øredev 2013

$0.65Principle:

"What’s best for the

customer"

Page 109: Refactor your specs! Øredev 2013

$0.65Principle:

"What’s best for the

customer"Could be implemented literally...

Page 110: Refactor your specs! Øredev 2013

Technically:

- Declarative code (brute force)- Rules engine...

Page 111: Refactor your specs! Øredev 2013

each pattern =

opportunity to simplify

Page 112: Refactor your specs! Øredev 2013
Page 113: Refactor your specs! Øredev 2013

each pattern =

opportunity of simplification

missed

Page 114: Refactor your specs! Øredev 2013
Page 115: Refactor your specs! Øredev 2013

Traditionally

Page 116: Refactor your specs! Øredev 2013

SpecificationsDescribe the system we

want to build

Page 117: Refactor your specs! Øredev 2013

SpecificationsOnce built,

specs become documentation

Page 118: Refactor your specs! Øredev 2013

SpecificationsOnce built,

specs become documentation

obsolete

Page 119: Refactor your specs! Øredev 2013

Now we know better...

Page 120: Refactor your specs! Øredev 2013

User StoriesAs a new visitorI want to registerIn order to receive spam

points: 1015

Page 121: Refactor your specs! Øredev 2013

ConversationsI want this button

more to the left

...

Page 122: Refactor your specs! Øredev 2013

BDD scenariosGiven I’m logged inWhen I click the Logoff buttonThen I’m logged off

Page 123: Refactor your specs! Øredev 2013

Perfect for many cases

Page 124: Refactor your specs! Øredev 2013

Richer domain,

more specs!

Page 125: Refactor your specs! Øredev 2013

Equations

Page 126: Refactor your specs! Øredev 2013

Rules

Taxes shall not be

changed retroactively

Page 127: Refactor your specs! Øredev 2013

State machines

Page 128: Refactor your specs! Øredev 2013

Workflows

Page 129: Refactor your specs! Øredev 2013

Common situation

+more details

Given I’m logged inWhen I click the Logoff buttonThen I’m logged off

Page 130: Refactor your specs! Øredev 2013

Often far from

perfect

Page 131: Refactor your specs! Øredev 2013

Often far from

perfect

Page 132: Refactor your specs! Øredev 2013

Too much upfront

Page 133: Refactor your specs! Øredev 2013

One-way

Page 134: Refactor your specs! Øredev 2013

Boring& Repetitive

Page 135: Refactor your specs! Øredev 2013
Page 136: Refactor your specs! Øredev 2013

So How to

Really improve this specs thing?

Page 137: Refactor your specs! Øredev 2013

Refactor your specs

Page 138: Refactor your specs! Øredev 2013

Refactor your specs

the way you think about

Page 139: Refactor your specs! Øredev 2013

The 3 amigos

Page 140: Refactor your specs! Øredev 2013

Just tell me what to do

Page 141: Refactor your specs! Øredev 2013

No, we need your skills to simplify and suggest

abstractions

TDD, refactoring, patterns...

Page 142: Refactor your specs! Øredev 2013

Just gimme examples, I’ll

reverse it all in TDD

Page 143: Refactor your specs! Øredev 2013

No, we need a true business perspective

DDD Ubiquitous Language

Page 144: Refactor your specs! Øredev 2013

I can only help once it’s

done

Page 145: Refactor your specs! Øredev 2013

No, you’re even more useful along the road, with your skills

on challenging everything

3 amigos & specification workshops

Page 146: Refactor your specs! Øredev 2013

Tester in India?

2+1 amigos

Page 147: Refactor your specs! Øredev 2013

IRL LOL

Page 148: Refactor your specs! Øredev 2013

I need specs to derive test

cases

Page 149: Refactor your specs! Øredev 2013

Why not collaborate during the workshops? We’ll do the test cases

at the same time

Specifications by Example

Page 150: Refactor your specs! Øredev 2013

Why not collaborate during the workshops? We’ll do the test cases

at the same time

Specifications by Example

scenarios

Page 151: Refactor your specs! Øredev 2013

EmailExcel

BDD toolWhatever

Page 152: Refactor your specs! Øredev 2013

My job is to solve problems &

tell what to do

Page 153: Refactor your specs! Øredev 2013

"90% of timeBA’s bring solutions"

- former head of BA’s

Page 154: Refactor your specs! Øredev 2013

Specs as "Amateur Design"

Page 155: Refactor your specs! Øredev 2013

Your job is to challenge the problem in-depth

Feature Injection, Impact Mapping

Page 156: Refactor your specs! Øredev 2013

If I don’t write a document I’m

useless!

Page 157: Refactor your specs! Øredev 2013

Relax! The document is always late to the party

Page 158: Refactor your specs! Øredev 2013

Real work is happening informally, while we talk.

Page 159: Refactor your specs! Øredev 2013

And you also have to facilitate and explain the business

domain to everyone

Page 160: Refactor your specs! Øredev 2013

Train the team

Page 161: Refactor your specs! Øredev 2013

new collaboration

Page 162: Refactor your specs! Øredev 2013

Specs -> Conversationsearly and frequent

between all 3 amigos

Page 163: Refactor your specs! Øredev 2013

Specs -> conversationsearly and frequent

But what about

documentation then?

Page 164: Refactor your specs! Øredev 2013

Living documentation[Gojko Adzic]

ExamplesIntent

(Free comments)

Page 165: Refactor your specs! Øredev 2013

Living documentation

Intent

Page 166: Refactor your specs! Øredev 2013

Living documentation

Concrete examples

Page 167: Refactor your specs! Øredev 2013

Living documentationFree comments

Page 168: Refactor your specs! Øredev 2013

Living documentation

Page 169: Refactor your specs! Øredev 2013

Visible Workings [Brian Marick]

Custom DocletRuntime exportLaTex export...

Page 170: Refactor your specs! Øredev 2013

- Annotate domain-relevant classes

- Custom Doclet to export Excel-formatted glossary of every domain concept

Source code as reference

Page 171: Refactor your specs! Øredev 2013

Source code as referenceSent directly to end customers

Page 172: Refactor your specs! Øredev 2013

Runtime exports

Page 173: Refactor your specs! Øredev 2013

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}

Page 174: Refactor your specs! Øredev 2013

Think critically

Page 175: Refactor your specs! Øredev 2013

Challenge things

Page 176: Refactor your specs! Øredev 2013

Refactor the code

Page 177: Refactor your specs! Øredev 2013

Refactor at the domain level too

Page 178: Refactor your specs! Øredev 2013

Exploit opportunitiesAs long as it’s in line with

the business domain

Page 179: Refactor your specs! Øredev 2013

- Introduce Just-In-Time specification workshops with the 3 amigos

- Consider Living Documentation

What about you?

Page 180: Refactor your specs! Øredev 2013
Page 181: Refactor your specs! Øredev 2013

Questions?Feedback?

@cyriux

Page 182: Refactor your specs! Øredev 2013

Merci