compositional

Mandatory 2 / Strategies
Note: I publish this presentation at the
week plan for week 4
Learning...
http://blogs.hbr.org/johnson/2012/09/throw-yourlife-a-curve.html
CS@AU
H B Christensen
2
Tides are turning?
Henrik Bærbak Christensen
3
A story about Kent Beck
I attended JAOO many years ago.
Kent Beck talked about design patterns
I asked him how I should do as a teacher?
– Pose problems to students, show DP afterwards?
– Show DP first, let students solve problem using DP
Henrik Bærbak Christensen
4
The response
Kent answered
Let them feel the pain...
Henrik Bærbak Christensen
5
Exercise: Why is this unfortunate?
In GameImpl:
Henrik Bærbak Christensen
6
Exercise: Why is this unfortunate?
In GameImpl:
Henrik Bærbak Christensen
7
The problem...
A theme of much code the TAs sends me is
You try to introduce strategies (compositional)
But wrap them in param./polym. designs
Result:
All liabilities from both methods
– Inflexibility and code bloat from the if (...) { } / subclass
– And all the extra classes and interfaces from
Composition
Henrik Bærbak Christensen
8
So – You will feel the pain
Henrik Bærbak Christensen
9
TDD: Maximize work not done
May this is unfair
– TDD:
Only do what is specified, do not think ahead
True, but if two solutions are about equal and
one only solves one problem, the other all – we
of course pick the general one
– int sum(x,y) { return x+y; }
– int sum(x,y) { if (x==2 && y==3) return 5; if (x==17&&
Henrik Bærbak Christensen
10
GammaCiv and UnitAction
GammaCiv and 36.11
GammaCiv: Settler and Archer action
– destroy settler, create city ; fortify archer
Two Solutions / polymorphic or compositional
– What/Who (behavioral focus / compositional):
•What: Encapsulate ’unit action’ = algorithm = Strategy
•Who: Game’s ’performUnitActionAt’ delegates...
– Who/What (model focus / polymorphic):
• Who: The settler ’does something’
•What: create city (and kill itself?); modify archer def. strength
Henrik Bærbak Christensen
12
Settler Action, Compositional
Strategy on performUnitActionAt
Henrik Bærbak Christensen
13
Settler Action, Compositional
Strategy on performUnitActionAt
Cohesion:
– High: GammaActionStrategy is highly focused; but potentially knows
many unit types (parametric switching) but in the delegate!!!
Coupling: Must know
– Unit (or just the type)
– Game
•Or rather methods to create city and destroy unit
•Or know city + world
– Cities’ unit making: just ”new UnitImpl(type);” - done
– GammaActionStrategy: has a switch on unit types...
Henrik Bærbak Christensen
14
Settler Action, Polymorphic
Polymorphic method on Unit
GameImpl.performAction() { ... u.action() }
Cohesion
– High: what a settler /archer does; but unit now ”knows a lot”
Coupling
–
–
–
–
City : Unit now coupled to City (”must say new StdCity()”);
World: Either direct access or ask Game to put city
Destroying: Cannot be done, must ask Game
Making settlers: abstract factory to make subtype outside HotCiv
framework (which contain a switch)– OR a switch on unit type
(no support for adding types later)
Henrik Bærbak Christensen
15
Polymorphic
Henrik Bærbak Christensen
16
Settler Action, Score Board
Which is the better? Compositional scores best...
Benefit
– Lower coupling (No Unit->”Others” coupling)
– Easier to create Units (all are alike except type string)
• Avoid need for factory system when it is a framework
– Unit destroying has to be made in Game anyway
– Easy to configure Game with new actions strategies
– Polymorphic must have a switch anyway! (just in another place)
Liabilities
– ActionStrategy will contain a type switch
•Parameterized variance but in ’external’ code.
– May become ’blob-code’, difficult to reuse...
Henrik Bærbak Christensen
17
Reuse of Strategies
Note that adding, say, a Chariot unit type can be
made purely by addition in compositional case...
– Compositional: add a ”XYZActionStrategy” which
•If (type.equals(”Chariot”)) { ...}
•else {
• [D].performUnitActionAt(p);
•}
– Where [D] is either
•super
in case new strategy inherits from the old one
•delegate in case we do composition
–Which is actually the decorator pattern
– Polymorphic: Add ChariotUnit + modify city code
Henrik Bærbak Christensen
18
More Fun stuff from trenches
Henrik Bærbak Christensen
19
Beta Winner – General or not?
Cities in AlphaCiv, how?
–
–
–
–
Matrix of City Objects? List of City Objects?
Matrix of Tile objects having reference to City object?
World class?
City redCity; blueCity; ???
Beta Winner: All cities conquered
– But Beta is Alpha which has only two cities???
– A) Iterate world, ensure all cities owned by player X
– B) redCity.getOwner() == blueCity.getOwner() ?
Henrik Bærbak Christensen
20
Maximize work not done
BetaCiv Winner
– First to conquer all cities in the world
But BetaCiv augments AlphaCiv in which no cities
can be produced!
– Winner algo: { if owner(c1) == owner(c2) return true; }
What if we later can produce cities?
– Then we must refactor winner algorithm
What if we never will be requested to produce
cities?
– The we have saved valuable time now
Dependency Injection
Merits
– All variant handling code in cohesive object
But think AbstractFactory handles it more
elegant
Henrik Bærbak Christensen
22
Variability is variable
(3) Encapsulate what varies
– Or Cutting the cake properly. It is difficult 
Henrik Bærbak Christensen
23
Multiple Maintenance 
Source code copy. Easy but costly!
– Here comes the Chariot!
Henrik Bærbak Christensen
24
NullObject
Avoid the if ( strategy != null ) pit fall:
if(unitActionStrategy == null) return;
Henrik Bærbak Christensen
25
Delegate Truely!
I say
– son.takeGarbageToCan()
I do not say
–
–
–
–
–
son.pickUpGarbage();
son.walkToCan();
son.openCanLid();
son.putGarbageIntoCan();
son.walkToHouse();
Exercise: Why is second version problematic?
Henrik Bærbak Christensen
26
Delegate Truely
Do not tell the strategy the invidiual steps!
Let the strategy take its responsibility!
– layoutStrategy.layoutWorld( tileList, cityList, unitList );
– Or similar...
Henrik Bærbak Christensen
27
Analyzability
Henrik Bærbak Christensen
28
Keep your Test code clean!
Do not duplicate AlphaCiv test cases in BetaCiv
Only include the Beta specific test cases
– Or better – unit test the WinnerStrategy...
Henrik Bærbak Christensen
29
Do not dispair 
TA presented a ‘nice solution’...
Morale: We often over-engineer 
Henrik Bærbak Christensen
30
Previous Years
Henrik Bærbak Christensen
31
Review your UML
”The blender is in the frog”
– Structure of sentences is important!
Dependency
– Rather vague
– Use assoc/aggr istead
Unit-GameImpl
– The wrong way around
Henrik Bærbak Christensen
32
Design
Pitfalls
Writing simple algorithms
Henrik Bærbak Christensen
33
”Accessor becomes Mutator” trap
I have seen this many times
As our code only calls ‘getWinner’ once per
round, it seems like a nice place to handle the
round increment.
What is the major problem in that?
Henrik Bærbak Christensen
34
Cohesive roles
Role well defined? Encapsulate what varies?
Henrik Bærbak Christensen
35
Cohesive roles
Problem:
– moveUnit is same for
all game variants
– performAction is not
Thus
– Variable + common
behaviour in same unit
=> one cannot change
without other affected
Group's solution
– Gamma inherits Alpha
Henrik Bærbak Christensen
36
Minor 'not so good'
I do not like the 'setGame'.
I would prefer
– performAction(game,pos);
– (I.e. Pass game instance
every time.)
Why?
Henrik Bærbak Christensen
37
Readability?
Positive:
– Comments!
Negative:
– Code duplication!
– Nesting level.
Henrik Bærbak Christensen
38
My refactoring
Note:
The tile type bugs are kept.
Henrik Bærbak Christensen
39
Which would you prefer to review ?
Henrik Bærbak Christensen
40
More of the same...
Writing simple algorithms...
How do I write 'simple' algorithms like moveUnit?
Use C style 'bail out': if (x) return;
Simplicity:
–
Take the simplest first (requires fewest info)
–
Intro more info as you need it (only then!)
–
Write the comments first (keep focus!)
Writing simple algorithms…
Try hard to avoid
– Conditionals with too many elements
• If ( cond1 && cond2 || cond3 )
– If you cannot avoid it, then unfold the conditions
• Boolean noUnitOnFrom = game.getUnitAt(p) == null;
• Boolean toCannotBeMovedTo = ...;
• If ( noUnitOnFrom || toCannotBeMovedTo ) return false;
– Use the C style bail-out, not Pascal style nested ifs
• If (bad) return false;
• If (! bad ) { ... } else { return false; }
Simple
Complex
Package structure
Common and variant code
Common = code that is executed in all variants
of the final delivered systems
– GameImpl
Variant = code (delegate) that is executed in one
or a few variants
Henrik Bærbak Christensen
44
More State
Pro: Learning exercise
Con: Overkill!!!
Henrik Bærbak Christensen
45
Misc...
Why not just use the Alpha strategy?
Henrik Bærbak Christensen
46
Unit versus System test
Important to test the game because it is what the
’costumer’ pays for
No test that ’move’ method will not move the
unit!
Henrik Bærbak Christensen
47
The mutable interface danger
Pro:
– Better to directly set the testable condition (set owner
of city to blue) than a lot of (defect-potential) code to
get the game into this situation
Con:
– Really really bad to introduce a mutator method in
City interface directly
Henrik Bærbak Christensen
48
Unit/Integeration testing
Many groups test AgingStrategy through Game
– That is: one zillion ”endOfTurn()”
Remember Unit testing
–
–
–
–
assertEquals( -4000, as.calcAge(0));
assertEquals( -100, as.calcAge(39));
assertEquals( -1, as.calcAge(40));
Etc.
Henrik Bærbak Christensen
49
UML Brush up 
Review class and sequence diagrams from your
old books 
Henrik Bærbak Christensen
50
Software View
Think roadmap!
– Avoid method names
Class
Navigability
Interface
Still – take care no to
overload with detail...
Much different from
conceptual view.
Henrik Bærbak Christensen
Realization/impl
51
Behavior
Sequence diagrams
Participant (object)
– Describe a single scenario
Timeline
Example
– Buy ticket sequence
creation
message
return
activation
self-call
Henrik Bærbak Christensen
52
Frames
Henrik Bærbak Christensen
53
Src-Code-Copy
No no no...
– Do not make a copy of AlphaCiv to begin working on
BetaCiv etc.
You can and will see this in practice, but...
This is not the intended learning outcome 
Henrik Bærbak Christensen
54
Clean Code That Works
...That Works is not enough...
Clean code means
– Refactoring you existing code
• Review coupling and cohesion
– Removing duplicated code
– Review method and variable names
• Do they convey the proper meaning?
– Create classes / packages
• Move methods / classes into better named software units
Henrik Bærbak Christensen
55
One Strategy to Rule Them All...
Henrik Bærbak Christensen
56
Beware
What will happen when...
– I have three different winner conditions
– I have four different aging strategies
– ... And eight different configurations of unit actions?
Combinatorial explosion of subclasses...
Henrik Bærbak Christensen
57
The Worst of Two worlds...
Henrik Bærbak Christensen
58
There Must Be a Switch Somewhere!
However, it is important where it is!
– Inside game
• You cannot add new variants expect by change by
modification
– In the main method /configuration code
• All the HotCiv code can be frozen into a JAR file that is not
going to be changed!
How often have you added a clause to a switch
inside Java Swing?
Henrik Bærbak Christensen
59
Getting Info Into the Strategies
How does WinnerStrategy know anything???
– Review Finn’s note on the web site...
Internal datastructure (like ’array of tile/city’)
– Sending internal data structure of GameImpl to the
strategy
• Higher coupling, cannot change datastructure later, no
encapsulation...
– Double references
• WinnerStrategy s = new BetaWinnerStrategy(game)
• Game game = new GameImpl(s);
• Better: return getWinner(this) in GameImpl...
Henrik Bærbak Christensen
60