Download presentation
Presentation is loading. Please wait.
Published byVanessa Walters Modified over 8 years ago
1
Mandatory 3 Test Stubs State Abstract Factory
2
Do not panic! dSoftArk is about Good analyzable design not about HotCiv! Henrik Bærbak Christensen2
3
Ecosense Karibu framework Henrik Bærbak Christensen3 RabbitMQ Mirrored Cluster MongoDB ReplicaSet / 3 Instances
4
Stubs – allow us to test! Henrik Bærbak Christensen4
5
Happy path test Henrik Bærbak Christensen5 Send the objects Validate they are stored in the DB
6
... on test doubles... Henrik Bærbak Christensen6
7
... And simulate failure situations Henrik Bærbak Christensen7
8
Back to HotCiv EpsilonCiv needs a die roll –Randomness makes auto testing inefficient –Stub the die! –Make a ‘PredictableDieStrategy’ with a void setSequence(int[] dieValuesToRoll); –... And of course a RealDieStrategy = random die And – inject the proper strategy for testing Henrik Bærbak Christensen8
9
Which one is the Test Stub? Henrik Bærbak Christensen9
10
This is not Abstract Factory! Henrik Bærbak Christensen10
11
This is not Abstract Factory! Henrik Bærbak Christensen11 Question: How to reconfigure at run-time?
12
AbsFactory – UML clutter... Henrik Bærbak Christensen12
13
Abstract Factory Hierarchy Question: –Interface: CivFactory –Subclass: AlphaFactory implements CivFactory –??: BetaFactory extends AlphaFactory Fine – Beta IS-A Alpha with some changes, so the subclass hierarchy works out OK – but naming bad! > Figure – > AbstractFigure –RectangleFigure, CircleFigure, LineFigure,... Extend AbstractFigure Henrik Bærbak Christensen13
14
Abstraction and parameterization When we introduce Green and Yellow player? Henrik Bærbak Christensen14
15
Design is About Being Consistent! If you decide to use Observer for you WinnerStrategy to solve ZetaCiv... Then you refactor this decision into existence consistently – or die the ‘if hell’ Henrik Bærbak Christensen15
16
Remember: Refactor Henrik Bærbak Christensen16
17
What can I do? Henrik Bærbak Christensen17
18
Appears General – but is not Henrik Bærbak Christensen18
19
Curiosities Henrik Bærbak Christensen19
20
State – and annoying state! Who stores what? Attacks won by player Henrik Bærbak Christensen20
21
Problem statement When doing compositional designs we –Cut behaviour that is often otherwise in the same abstraction, and therefore have access to the same state (i.e. The same set of instance variables)... Parametric: all in the same class Polymorphic: subclasses still contain all of superclass var. –... Into multiple objects But how do they share/exchange state!!! Henrik Bærbak Christensen21
22
Example WinnerStrategy: Algorithm to determine winner Based upon knowledge of –Alpha: The age (correlates to rounds) –Beta: Owner of all cities –Epsilon:Attacks won by player –Zeta:Rounds+Beta+Epsilon’ Epsilon’ = counting only starts after 20 rounds But who is responsible for ”knowing it”? Henrik Bærbak Christensen22
23
Example Who should know it? –Game or the WinnerStrategy or some third object? –Game/WinnerS: Number of rounds played/age –Game: Owner of all cities –WinnerS:Attacks won by player –WinnerS:Counting only starts after 20 rounds Known by Game Not really known by the Game Henrik Bærbak Christensen23
24
Solution 1 Let the GameImp store all this state + provide accessor methods for them Fine for –Game/WinnerS: Number of rounds played –Game: Owner of all cities –See Finn’s note on the weekplan But should game count attacks? –Augment the Game interface? Or GameImpl? See Finn’s discussion of ’Private Interfaces’ –Change game to suit a single strategy? Henrik Bærbak Christensen24
25
Solution 2 Augment the WinnerStrategy interface, to capture state –incrementRoundCount(); –incrementAttacksWon(Player p); –cityOwnerChanged(Position p); –All info local to the winner algorithm (cohesion) –No irrelevant data captured in Game (cohesion) –No accessor methods introduced in Game only for the strategy –GameImpl has to invoke these methods (and only once!) (low cohesion) –Many strategies do not need that info anyway Well-known property of Strategy –Not open to further weird strategies Henrik Bærbak Christensen25
26
Solution 3 (bit similar to 2) Rather complex solution but with merits... –Create a GameEventObserver, let GameImpl call its methods: cityCreated(Position p) attackPerformed(Unit winner); roundIncrement(); Let our strategy register as observer of the game –Can do its own counting = no irrelevant state in Game –But GameImpl has to call ‘notifyAttackWonBy(p)’ –Can be used for other purposes, like scoring graphs –Can probably suit new strategiest that count other stuff... Henrik Bærbak Christensen26
27
Scores... Basically we either –1) Add strategy specific state into Game That is not used by most variants State has to be properly maintained (remember to incr. Battel counter) –2) Add strategy specific method calls into Game That lowers readability of game That obey a sensitive protocol –i.e. ’global analysis’ of GameImpl to ensure that ’incrementBattleCount()’ is called once and only once (Observer solution is basically a variant of this theme) Which is the lesser evil? Henrik Bærbak Christensen27
28
But make it general! This is a ’responsibility eroding’ way of doing it This is basically a parametric solution! If ( variant == ZetaCiv ) { [increment counter] } Thus you get the worst of both world Henrik Bærbak Christensen28 In game.moveUnit: if(winnerstrategy instanceof BattleWinner) { ((BattleWinner) winnerstrategy).winBattle(unit.getOwner(), this); }
29
Others Solution 1) / battle counter in Game + A ’resetBattleCount()’ in GameImpl –Invoked by the strategy after the 20th round Bad idea! –State in game => other parts may start using this information –But in one variant the count mysteriously resets after 20 rounds??? Henrik Bærbak Christensen29
30
36.18: Alpha map = a test stub? A wonderful discussion with TAs –”AlphaCiv map defined by particular customer, thus it is not a test stub” It is in a production code folder This is of course right, but... –World layout optimized to support testing Supports ’evident test’ (units close for testing terrain) Is static (no randomness) –Thus feeds indirect input, defined by test code Henrik Bærbak Christensen30
31
(so what is the answer?) The answer (as often in this course) is Sound and clear Argumention On one hand Alpha Map exhibits –(arguments in favour of considering it a test stub) On the other hand –(arguments in favour of considering it a test stub) Therefore we conclude – Henrik Bærbak Christensen31
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.