1 / 25

Agile Design

Agile Design. What is Agile Design? SRP OCP LSP DIP ISP. Agile Design. What is Agile Design? SRP OCP LSP DIP ISP. What is Agile Design?. Design is the structure of the system, modules, classes, methods Some aspects of it may be illustrated in UML diagrams

bsesco
Download Presentation

Agile Design

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Agile Design What is Agile Design? SRP OCP LSP DIP ISP

  2. Agile Design • What is Agile Design? • SRP • OCP • LSP • DIP • ISP

  3. What is Agile Design? • Design is the structure of the system, modules, classes, methods • Some aspects of it may be illustrated in UML diagrams • Design commonly degrades as the system is changed • Requirements do change, so the system has to change • Initially sound design rots to pieces • Result suffers from code smells • Rigidity, Fragility, Immobility, Viscosity, Needless Complexity (YAGNI), Needless Repetition (DRY), Opacity • Changes are often made simple instead of design preserving (opacity) • Example: Copy program • Cluttered with fixes instead of refactored to Open-Closed Principle

  4. The Copy Program • Original program • Copy from keyboard to printer • void Copy(){ int c; while ((c=RdKbd()) != EOF) WrtPrt(c);} • Change requirements • Allow input to be taken from paper tape as well • Allow output to go to the paper punch as well

  5. The Modified Copy Program • The modified program • bool ptFlag = false;bool punchFlag = false;// remember to reset these flagsvoid Copy(){ int c; while ((c=(ptFlag ? RdPt() : RdKbd()) != EOF) punchFlag ? WrtPunch(c) : WrtPrt(c);} • Design flaws • Rigid (changes ripple), Fragile (breaks easily), Immobile (hard to reuse parts), Complex (all logic entangled in main loop), Redundant (replicated logic), Opaque (hard to understand) • Modified requirements squeezed into original design

  6. The Refactored Copy Program • Refactoring to design standards (after first requirement change) • public abstract class Reader{ abstract int read();}public class KeyboardReader : Reader{ override int read(){ return RdKbd(); }}KeyboardReader defaultReader = new KeyboardReader();void Copy() { Copy(defaultReader);}void Copy(Reader reader){ int c; while ((c=reader.read()) != EOF) WrtPrt(c);}

  7. Principles and Patterns in Refactored Copy Program • Open-Closed Principle (OCP) • New input devices do not require source code changes any more • Solution is open for extensions, but closed for modifications • With respect to changes in input devices • Dependency Inversion Principle (DIP) • In original design, main module (policy) was dependent on low-level details • Made it sensitive to changes in submodules (policy implementations) • After refactoring, submodules are dependent on higher-level interface • Main module uses same interface, insensible to implementation changes • Strategy Design Pattern • Detailed low-level implementation supplied to main module from the outside • Allows change in behaviour without main module caring about details • Avoid Needless Complexity (YAGNI) • Wait as long as possible before refactoring • Until there is a need to change output devices, don’t make a solution for it

  8. Agile Design • What is Agile Design? • The Single Responsibility Principle, SRP • OCP • LSP • DIP • ISP

  9. A Class should represent One and only One Concept • A Class should represent One and only One Concept • It should be Coherent (all elements functionally related) • It should have only one Reason to Change • Anti-example: Bowling Game • Responsible of both current frame and of calculating score • Separate in Game to keep track of frames, and Scorer to calculate score • Each responsibility is an axis of change • Separating them allows changes to be made for fewer reasons • Allows for less fragile design • Only if that change actually occurs • Typical mixtures of responsibilities • Logic and user input/output, or logic and persistence control • Change at different rates and for different reasons and should not be mixed

  10. Agile Design • What is Agile Design? • SRP • The Open-Closed Principle, OCP • LSP • DIP • ISP

  11. Open for Extension, Closed for Modification • Software entities (classes, modules, functions, etc.) should be • Open for extension • It is possible to add new behaviour to it • Closed for modification • Extension does not cause modifications in source or binary code • Make client modules work with abstractions • Not implementations • But only when there actually is a change (YAGNI) • Resisting premature abstraction is as important as abstraction itself • You may stimulate or anticipate (YAGNI risk!) the change • Abstractions may be • Abstract classes or interfaces • Abstract methods, Template Method (”Hollywood”) Design Pattern • Implemented in subclasses

  12. Example in C#: IComparer • In C#, the generic class List<T> has a static method Sort • aList.Sort(aComparer) • aComparer class implements IComparer<T> • Sort compares pairs of elements in the list using the comparer • if (aComparer.Compare(e1, e2) > 0) Swap(e1, e2); • Compare returns a negative, zero or positive number indicating sorting order • The comparer knows about sorting order of elements of type T • The list does not • The class List<T> is • Open for extension of new sorting orders • Closed for modification with regard to such extensions

  13. Agile Design • What is Agile Design? • SRP • OCP • The Liskov Substitution Principle, LSP • DIP • ISP

  14. How to apply inheritance and conform to the OCP? • Subtypes must be substitutable for their base types • public class B{ virtual void f(){...}}public class D : B{ override void f(){...}} • In the client: • B anObject = new D();anObject.f(); • The client will behave as if it had a B object • So f in D must behave as f in B, or the client will be confused

  15. Counter-example: Square ”is a” Rectangle • Square is a rectangle • public class Square : Rectangle {...} • public Rectangle GimmeAShape(){...}// returns either • Rectangle client getting a rectangle • Rectangle r = GimmeAShape(); // gets a rectangler.setWidth(3); r.setHeight(4);if (12 != r.getArea()) driveMeNuts(); // puh, ok • Square client getting a square • Rectangle r = GimmeAShape(); // gets a squarer.setWidth(3); r.setHeight(4);if (12 != r.getArea()) driveMeNuts(); // arghhh, 16! • A square does not behave like a rectangle • So the client gets confused when square says it is a rectangle

  16. LSP, Design by Contract, and TDD • A subclass obeys the LSP if, for all overriding methods • The precondition is the same or weaker than in the base class • The postcondition is the same or stronger than in the base class • For all cases that satisfy the original precondition from the base class • Or, said differently, the contract is the same or weaker than in the base class • A test case for a base class method should run unchanged for a subclass override • The input conditions should satisfy the override • The override should satisfy all the outcome expectations • The collection of test cases implicitly defines the contract

  17. LSP Example: Stack • Abstract class Stack, with UnboundedStack, BoundedStack • public abstract class Stack { public void push(Element e) {...} // Pre: !IsFull() abstract bool IsFull();} • public class UnboundedStack : Stack { override bool IsFull() {return false;}} • public class BoundedStack : Stack { override bool IsFull() {return this.spaceLeft() == 0;}} • Client code is independent of which kind of stack it uses • Stack s = GimmeAStack(); // may return eitherif (!s.IsFull()) s.push(new Element()); // works with either

  18. Agile Design • What is Agile Design? • SRP • OCP • LSP • The Dependency Inversion Principle, DIP • ISP

  19. Depend on Abstractions, Not on Details • High-level modules should not depend on low-level modules • Both should depend on abstractions • Abstractions should not depend on details • Details should depent on abstractions • Define an interface for services needed by a higher (policy) layer • Let lower (mechanism) layers implement that interface • Invert top-down dependency to bottom-up • If lower-layer classes are likely to change (beware of YAGNI) • The upper layer client needs to own the interface • Breaks dependency on lower, implementation layers • Makes the upper layer module more reusable

  20. DIP Example: Light Switch • Button, when pressed, turns on or off a lamp • public class Button{ private Lamp lamp = new Lamp(); public void Poll(){ if (/*some condition*/) lamp.On(); else lamp.Off(); }} • Button directly depends on lamp • Cannot be used with any other device

  21. Invert Depencencies • Reuse design for other devices, like motors • public interface SwitchableDevice{ void On(); void Off();} • Make both button and lamp depend on SwitchableDevice • public class Lamp : SwitchableDevice{ // implement On and Off} • public class Button{ private SwitchableDevice device; public Button(SwitchableDevice device) {...} public void Poll(){ if (/*some condition*/) device.On(); }} • Both button and SwitchableDevice are separately reusable

  22. Agile Design • What is Agile Design? • SRP • OCP • LSP • DIP • The Interface-Segregation Principle, ISP

  23. Clients should Know about Cohesive Interfaces • Fat classes cause bizarre and harmful couplings between their clients • When one client forces a change on the interface, all the others are affected • Avoid accumulated, fat interfaces • A client should not be forced to depend on methods that it does not use • Should only relate to methods it uses itself • A class chould not be forced to be recompiled • Because some other class causes a change in the interface unrelated to our class • Separate fat interfaces in cohesive blocks • Separation through delegation: Using an object adapter • Separation through Multiple Inheritance

  24. Timed Door

  25. Separation through ”multiple inheritance”

More Related