Hints - Mandatory 2 / Strategies. Learning... life-a-curve.html B Christensen2 Jeg fatter ikke.

Slides:



Advertisements
Similar presentations
Revealing the Secrets of Self-Documenting Code Svetlin Nakov Telerik Corporation For C# Developers.
Advertisements

Composition CMSC 202. Code Reuse Effective software development relies on reusing existing code. Code reuse must be more than just copying code and changing.
Test-Driven Development and Refactoring CPSC 315 – Programming Studio.
Refactoring Overview  What is refactoring?  What are four good reasons to refactor?  When should you refactor?  What is a bad smell (relative to refactoring.
The Bridge Pattern.. Intent Decouple an abstraction from its implementation so that the two can vary independently Also known as: Handle/Body.
Week 2 Design Examples and Designing for Change Alex Baker.
Prototype Creational Design Pattern By Brian Cavanaugh September 22, 2003 Software, Design and Documentation.
Regression testing Tor Stållhane. What is regression testing – 1 Regression testing is testing done to check that a system update does not re- introduce.
What Is a Factory Pattern?.  Factories are classes that create or construct something.  In the case of object-oriented code languages, factories construct.
Maintenance Refactoring and Code Smells. Where are we? Over the semester we have talked about Software Engineering. The overall goal of software engineering.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
OOD Case Study (For parallel treatment, see Chapter 2 of the text)
Programming in Java Unit 2. Class and variable declaration A class is best thought of as a template from which objects are created. You can create many.
Designing classes How to write classes in a way that they are easily understandable, maintainable and reusable 3.0.
CSC 211 Introduction to Design Patterns. Intro to the course Syllabus About the textbook – Read the introduction and Chapter 1 Good attendance is the.
By the end of this session you should be able to...
CS 350 – Software Design The Strategy Pattern – Chapter 9 Changes to software, like other things in life, often focus on the immediate concerns and ignore.
Best Practices. Contents Bad Practices Good Practices.
Software Engineering CS3003 Lecture 4 Code bad smells and refactoring.
REFACTORINGREFACTORING. Realities Code evolves substantially during development Requirements changes 1%-4% per month on a project Current methodologies.
Module 3. Smells Between Classes Course: Refactoring.
Designing Classes. Software changes Software is not like a novel that is written once and then remains unchanged. Software is extended, corrected, maintained,
Behavioral Patterns CSE301 University of Sunderland Harry R Erwin, PhD.
The HotCiv GUI Instantiating the MiniDraw Framework.
Test Stubs... getting the world under control. TDD of State Pattern To implement GammaTown requirements I CS, AUHenrik Bærbak Christensen2.
Scalatest. 2 Test-Driven Development (TDD) TDD is a technique in which you write the tests before you write the code you want to test This seems backward,
CS 350 – Software Design Expanding Our Horizons – Chapter 8 The traditional view of objects is that they are data with methods. Sometimes objects could.
Testing OO software. State Based Testing State machine: implementation-independent specification (model) of the dynamic behaviour of the system State:
Henrik Bærbak Christensen1 Test Driven Development “TDD” Summary.
ANU COMP2110 Software Design in 2003 Lecture 10Slide 1 COMP2110 Software Design in 2004 Lecture 12 Documenting Detailed Design How to write down detailed.
SEG 4110 – Advanced Software Design and Reengineering Topic T Introduction to Refactoring.
HotCiv Project Starting up!. Henrik Bærbak Christensen2 HotCiv = Agile development Iterations of –product development –learning increments.
Deriving State…...and an example of combining behaviour.
All the dSoftArk Tools Getting started!. Tools dSoftArk is a semi-realistic, agile, development project –Industrial strength software (programming, TDD,
Refactoring Agile Development Project. Lecture roadmap Refactoring Some issues to address when coding.
1 COS 260 DAY 12 Tony Gauvin. 2 Agenda Questions? 5 th Mini quiz –Chapter 5 40 min Assignment 3 Due Assignment 4 will be posted later (next week) –If.
Session 7 Introduction to Inheritance. Accumulator Example a simple calculator app classes needed: –AdderApp - contains main –AddingFrame - GUI –CloseableFrame.
Multi Dimensional Variance: How to make ultra flexible software!
Mandatory 1 / AlphaCiv … Traps to be aware of …. Warn or not? I once asked Kent Beck the following –I have a lot of students in a course in design patterns.
Applying the Principles Two Examples. Example 1 New Requirement It would be nice with a simple GUI “to see something” instead of just xUnit tests...
Refactoring and Integration Testing or Strategy, introduced reliably by TDD The power of automated tests.
AU CSHenrik Bærbak Christensen1 dSoftArk Software Architecture Programming in the Large.
MiniDraw Introducing a Framework... and a few patterns.
Mandatory 2 / Strategies Note: I publish this presentation at the week plan for week 4.
Behavioural Patterns GoF pg Iterator GoF pg. 257 – 271 Memento GoF pg By: Dan Sibbernsen.
Mandatory 1 / AlphaCiv … a few comments…. Overall: Generally – good work – good effort Seems you are generally doing TDD Minor hick-ups –”My own way is.
Patterns are Roles What patterns are and what not…
Software Architecture Quality Attributes. Good or Bad? Measurable criterions required...
Continuous Improvement. Start Simple and Continually Improve E.g., Gmail Labels 1.
CS, AUHenrik Bærbak Christensen1 Compositional Design Principles The “GoF” principles Or Principles of Flexible Design.
Mandatory 3 Test Stubs State Abstract Factory. Stubs, Spies, and Fake Objects One Example Making distribution testable... Henrik Bærbak Christensen2.
Mandatory 3 Test Stubs State Abstract Factory. Do not panic! dSoftArk is about Good analyzable design not about HotCiv! Henrik Bærbak Christensen2.
Strategy in 15 minutes... derived from the principles.
CSHenrik Bærbak Christensen1 Flexibility and Maintainability And their metrics: coupling and cohesion.
Hints - Mandatory 5 Blackbox Testing Pattern Hunting.
Instantiating the MiniDraw Framework
Introducing a Framework ... and a few patterns
Generalizing Similar Functions
Applying the Principles
HotCiv Project Starting up!.
Mandatory 1 / AlphaCiv … Traps to be aware of ….
Generalizing Similar Functions
Software Engineering and Architecture
Software Engineering and Architecture
HFOOAD Chapter 5 Interlude
Software Engineering and Architecture
Software Engineering and Architecture
Software Engineering and Architecture
Software Engineering and Architecture
Software Engineering and Architecture
Presentation transcript:

Hints - Mandatory 2 / Strategies

Learning... life-a-curve.html B Christensen2 Jeg fatter ikke en bjælde!?! Aah, det giver da lidt mening!

TDD being standard? Henrik Bærbak Christensen3

Fake-it is a strong tool... To help new abstractions into development as part of keeping focus on something else. Check out the screencast on weekplan 2 (unit- move-faked). Feature: moveUnit –Require a data structure for storing units in the world, so a World role is faked to keep focus on the moveUnit method... Henrik Bærbak Christensen4

Java 8 and Lambda expressions Java 8 (finally) introduced lambda’s –Inline code blocks Henrik Bærbak Christensen5

Sprint 2 Functional requirements –Develop and maintain 4 variants Beta: Alternative winning and aging algorithm Gamma: Allows some units to do an action Delta: Alternative world layout –All are variants of AlphaCiv Real requirementsReview the rubrics! –Use AlphaCiv tests to support refactoring GameImpl into a compositional design (strategy pattern) –Demonstrate and argue for your design Remember to TDD the new variant implementations Remember unit and integration testing Henrik Bærbak Christensen6

Great discussions “Your specification of feature X in HotCiv is unclear, Henrik!” –Yes. Face it – this is how real life is! –Agile method’s answer: Ask the customer! “on-site customer” / “product owner” My answer is always –I do not really care about functionality This is not an algorithm course! –dSoftArk is about flexible reliable design This is a software architecture course So: pick the simplest algorithmic solution that fit the requirement and spend the time on a flexible and reliable design Henrik Bærbak Christensen7

Best way to code... Grab yourself a copy of Uncle Bob’s book ! Ask on the web board! And read the comments –Best way to structure packages ? Good question Henrik Bærbak Christensen8

Conditionals are hard to read!!! Is this code correct for moveUnit If it is hard to write then –It is probably buggy! –You yourself cannot understand it in two weeks –Bjarne will never ever be able to understand it Beware when he comes around and “fixes” it!!! Henrik Bærbak Christensen9

Real example...

Remedy 1: Fail-fast Think which conditions allows me to bail out immedately? Henrik Bærbak Christensen11

Remedy 2: Take small steps Divide and conquer. Take small steps. Henrik Bærbak Christensen12

Often more analyzable to ‘patch’ Henrik Bærbak Christensen13 Plains

Side note Simplicity – Maximize work not done Henrik Bærbak Christensen14 Remember – A GUI handles a lot of cases for us so it is actually wrong to implement code that handles situations that violate preconditions! And to make test cases for it!

Fake-it till you make it Fake-it is a wonderful pattern but should be removed and replaced by proper general algorithms as soon as possible!!! Anti example –We must develop: int sum(x,y) –Iteration 1: assertEquals( 3, obj.sum(1,2) ); int sum(int x, int y) { return 3; } –Iteration 2: assertEquals( 5, obj.sum(3,2) ); int sum(int x, int y) { if (x==3 && y==2) return 5; else return 3; } Henrik Bærbak Christensen15 This is a catastrophe and has nothing to do with TDD!

Exercise: Why is this unfortunate? In GameImpl: Henrik Bærbak Christensen16

Exercise: Why is this unfortunate? In GameImpl: Henrik Bærbak Christensen17

The problem... A theme of much code last years: 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 Christensen18

GammaCiv and UnitAction

GammaCiv and GammaCiv: Settler and Archer action –destroy settler, create city ; fortify archer Two Solutions / polymorphic or compositional –Who/What (model focus / polymorphic): Who: The settler ’does something’ What: create city (and kill itself?); modify archer def. strength –What/Who (behavioral focus / compositional): What: Encapsulate ’unit action’ = algorithm = Strategy Who: Game’s ’performUnitActionAt’ delegates... Henrik Bærbak Christensen20

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 Christensen21

Polymorphic Henrik Bærbak Christensen22

Settler Action, Compositional Strategy on performUnitActionAt Henrik Bærbak Christensen23

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 Christensen24

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 Christensen25

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 superin case new strategy inherits from the old one delegatein case we do composition –Which is actually the decorator pattern –Polymorphic: Add ChariotUnit + modify city code Henrik Bærbak Christensen26

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 Christensen27

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 Christensen28

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 Christensen29

More Fun stuff from trenches Henrik Bærbak Christensen30

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 Christensen31

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 Christensen33

Variability is variable (3) Encapsulate what varies –Or Cutting the cake properly. It is difficult Henrik Bærbak Christensen34

Multiple Maintenance  Source code copy. Easy but costly! –Here comes the Chariot! Henrik Bærbak Christensen35

NullObject Avoid the if ( strategy != null ) pit fall: Henrik Bærbak Christensen36 if(unitActionStrategy == null) return;

Do not dispair TA presented a ‘nice solution’... Morale: We often over-engineer Henrik Bærbak Christensen37

Previous Years Henrik Bærbak Christensen38

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 Christensen39

Design Pitfalls Writing simple algorithms Henrik Bærbak Christensen40

”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 Christensen41

Cohesive roles Role well defined? Encapsulate what varies? Henrik Bærbak Christensen42

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 Christensen43

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 Christensen44

Readability? Henrik Bærbak Christensen45 Positive: –Comments! Negative: –Code duplication! –Nesting level. Code duplication leads to bugs! Exercise: Find duplication bug

My refactoring Henrik Bærbak Christensen46 Note: The tile type bugs are kept.

Which would you prefer to review ? Henrik Bærbak Christensen47

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;Simple If (! bad ) {... } else { return false; }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 Christensen51

More State Henrik Bærbak Christensen52 Pro: Learning exercise Con: Overkill!!!

Misc... Why not just use the Alpha strategy? Henrik Bærbak Christensen53

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 Christensen54

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 Christensen55

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 Christensen56

UML Brush up Review class and sequence diagrams from your old books Henrik Bærbak Christensen57

Henrik Bærbak Christensen58 Software View Think roadmap! –Avoid method names Still – take care no to overload with detail... Much different from conceptual view. Navigability Class Realization/impl Interface

Henrik Bærbak Christensen59 Behavior Sequence diagrams –Describe a single scenario Example –Buy ticket sequence Participant (object) message return self-call creation Timeline activation

Frames Henrik Bærbak Christensen60

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 Christensen61

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 Christensen62

One Strategy to Rule Them All... Henrik Bærbak Christensen63

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 Christensen64

The Worst of Two worlds... Henrik Bærbak Christensen65

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 Christensen66

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 Christensen67