Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS5103 Software Engineering Lecture 09 Software Design and Design Patterns.

Similar presentations


Presentation on theme: "CS5103 Software Engineering Lecture 09 Software Design and Design Patterns."— Presentation transcript:

1 CS5103 Software Engineering Lecture 09 Software Design and Design Patterns

2 2 Last class  Sequence diagrams  Software architecture  Why? Higher level design of larger software projects  Software architectural styles  Pipe and Filter  Layered  Repository

3 3 Today’s class  Software Design  Process  Factors  Measures  Design Patterns  Composite pattern  Factory pattern  Visitor pattern

4 4 Software Design Process  Software design is usually created in two stages  Architecture design  Detail design (component-level design)  Design patterns  Design classes  Design review  Other design issues  Refactoring  UI Design

5 5 Software Design Factors  Fundamental software design factors  Modularity  Abstraction  Information hiding  Component independence  Fault prevention and fault tolerance

6 6 Modularity and Abstraction  When we consider modular solutions to any problems, many levels of abstraction can be posed At the highest level of abstraction, a solution is stated in broad terms of problem domain: architecture At the lower levels of abstraction, a more detailed description of the solution is provided: class diagrams  Modularity hides details and facilitates evolvement Each component hides a design decision from the others

7 7 Component Independent  We strive in most designs to make the components independent of one another, why?  We measure the degree of component independence using two concepts Low coupling High cohesion

8 8 Coupling and Cohesion  Coupling Two components are highly coupled when there is a great deal of dependence between them Two components are loosely coupled when they have some dependence, but the interconnections among them are weak Two components are uncoupled when they have no interconnections at all  Cohesion A component is cohesive if the internal parts of the component are related to each other and to its overall purpose

9 9 Decoupling  Most difficult part in design: Need tradeoff  Consider the following case:  Online and offline bookstore components  Both need shopping cart checkout  Should we have a shopping cart checkout module for both of them? Or have one, and let the two components to call the module?  Consider potential changes on overall book discount policy and specific book discount policy?  Solution for the dilemma: break the checkout module, still not perfect 

10 10 Fault defense & tolerance  Defensive design anticipates situations the might lead to problems Network Failure Data corruption Invalid user inputs  Tolerate runtime errors Exception handling Redundant components (distributed system or critical software) Timely error reporting

11 11 Criteria for Good Software Design  High-quality designs should have characteristics that lead to quality products Correct translation from the requirements specification Ease of understanding Ease of implementation Ease of testing Ease of modification

12 12 Criteria for Good Software Design  Architecture  Using suitable architectural styles or patterns  Loose-coupled components  Can be implemented in an evolutionary fashion  Classes at a suitable abstract level  Interfaces are clear and minimize the data transfer  Design using a effective notation

13 13 Software Design Evaluation and Validation  We check a design in two different ways Validation: the design satisfies all requirements specified by the customer Verification: the characteristics (quality) of a good design are incorporated  We use some techniques for helping us to perform verification and validation Measuring design quality Design reviews

14 14 Measuring Software Design Quality  We check a design using a set of measures Coupling Cohesion Complexity Basic metrics: size Depths of relations Cyclomatic complexity

15 15 Design reviews  We check a design  Designers  Customers  Analysts  prospective users  Developers  Moderator leading the discussions  Secretary recording the issues

16 16 Design Patterns  Become popular due to a book  Design Patterns: Elements of Reusable Object- Oriented Software  Gang of Four: Gamma, Erich; Richard Helm, Ralph Johnson, and John Vlissides  Provide solutions for common problems in micro-design

17 17 Design Patterns Structure  Name  Important to know for easier communication between designers  Problem solved  When to apply the pattern  Solution  Usually a class diagram segment (sometimes attributes and operations)

18 18 Design Patterns  Structure Patterns  Composite  Creation Patterns  Factory  Behavioral Patterns  Visitor

19 19 Running Example  A Document Editor  Text and graphics can be freely mixed  Graphical user interface  Support different look-and-feel GUI styles  Traversal operations: spell checking

20 20 Composite Pattern: Example  A document is represented by structure  Primitive glyphs  Characters, circles, pictures  Lines: A sequence of glyphs  Columns: A sequence of Lines  Pages: A sequence of Columns  Documents: A sequence of Pages

21 21 Example of Hierarchical Document

22 22 Possible Designs?  Classes of Character, Circle, Pictures, lines, Columns, pages, document  Composition relationship between classes  Not so good, why?  A lot of duplication:  all classes has onClick, draw behavior  Difficult to add or remove levels in hierarchy  Traverse/display operations need to change for any change of the hierarchy

23 23 Alternate Designs  One class of Glyph  All elements are subclasses of Glyph  All elements uniformly present the same interface  How to draw  Computing bounds  Mouse hit detection  …  Make extending the class easier

24 24 Logic Object Structure

25 25 Logic Object Structure

26 26 Composite Pattern  Applies to any hierarchy structure  Leaves and internal nodes have similar functionality  Pros:  Easy to add, remove new types  Clean interface  Cons:  Add corner cases  Enforce certain type of elements only have certain types of children

27 27 Problem: Supporting look-and-feel settings  Different look-and-feel standards  Appearance of scrollbars, menus, windows, etc., set by the user  We want to support them all  For example: having classes MotifScrollBar and WindowsScrollBar  Both are subclasses of ScrollBars  How should we create a new scrollbar in a window?

28 28 Possible designs?  Terrible ScrollBar sc = new WindowScrollBar();  Better, problems? If (style==MOTIF){ sc = new MotifScrollBar(); }else{ sc = new WindowScrollBar(); }  Conditions for other UI elements: menus, etc.  Hard to add new styles

29 29 Factory Pattern  One method to create a look-and-feel dependent object  Define a GUIFactory Class  One GUIFactory object for each look and feel  Create itself using conditions set by the user

30 30 Factory Pattern

31 31 Factory Pattern: factory design abstract class GUIFactory{ abstract ScrollBar CreateScrollBar(); abstract Menu CreateMenu();... } class MotifFactory extends GuiFactory{ ScrollBar CreateScrollBar(){ return new MotifScrollBar() } Menu createMenu(){ return new MotifMenu(); }... }

32 32 Factory Pattern: GUI code GuiFactory factory; if(style==MOTIF){ factory = new MotifFactory(); }else if(style==WINDOW){ factory = new WindowFactory(); }else{... } ScrollBar bar = factory.createScrollBar(); Menu mn = factory.createMenu();

33 33 Factory Pattern  Applies to the object creation of a family of classes  The factory can be changed at runtime  Pros & Cons  Lift the conditional creation of objects to the creation of factories  Flexible for add new type of objects  Sometimes make the code more difficult to understand

34 34 Spell Checking Problem  Considerations  Requires to traverse the document  Need to see every glyph in order  There maybe other analyses that require traverse the document  Counting words, Grammar checking

35 35 Possible design class Glyph{… void spellCheck(char[] curWord): for(int i = 0; i<this.children.length; i++): this.children[i].spellCheck(curWord); if(this isa character): if(this == space): Util.SpellCheck(curWord); curWord.clear(); else: curWord.append(this); …}

36 36 Other Actions  Document Stats  counting words,  counting pictures,  counting lines, columns, pages)  Find a word  Change line-break rules  …

37 37 Now we have  A large number of similar methods  All need to traverse the document  Code duplication always causes problems  change the data structure of “children” from array to list (better insertion and deletion)  Skip full-picture page to enhance performance for word-related tasks

38 38 Solution  Visitor pattern  Decouple traverse process and action  Write traverse code only once  Each element in the hierarchy under traverse has an “action” code

39 39 Visitor pattern basic design class Glyph{… void scan(Visitor v): for(int i = 0; i<d.children.length; i++): d.children[i].scan(v); …} We have different visitors: spellcheckVisitor, documentStatVisitor, etc.

40 40 Solution

41 41 Code of SpellCheckVisitor class SpellCheckVisitor extends Visitor{ char[] curWord = {}; void visitChar(Character c){ if(c==SPACE): spellCheck(curWord); curWord.clear(); else: curWord.add(c); }

42 42 Still have problems  How about counting all glyphs (including picture, character, circle)?  Need to change visitPicture, visitCharacter, and visitCircle?  Add visitGlyph

43 43 Add VisitGlyph class Glyph{ … scan(Visitor){ for each c in children: v.visitGlyph(c) c.Scan(v) } … }

44 44 Code of CountGlyphVisitor class CountGlyphVisitor extends Visitor{ int count = 0; void visitGlyph(Glyph g){ if(g.children.length==0): count++; }

45 45 Summary of design patterns  Major aim: decoupling  pros:  more flexibility  less changes when modification is required  Cons:  not intuitive at the beginning, harder to read code, but get easier when you are familiar with the pattern  Trouble for verifications and analysis (often not scalable without a design pattern)  So it is rather popular!

46 46 Other useful design patterns  Observer  Facade  Factory method  Decorator  Bridge  See them in wiki pages or read the book  Design Patterns: Elements of Reusable Object-Oriented Software

47 47 Today’s class  Software Design  Design process  Design factors  Design evaluation  Design Patterns  Composite pattern  Factory pattern  Visitor pattern

48 48 Next Class  Software Implementation: Versioning  Why versioning?  Versioning tools  CVS  SVN  GIT

49 49 Thanks!

50 50 A controversial pattern: singleton pattern  Problem  How to make sure a class only has one object  File system  Windows manager  …  The class itself is made responsible for keeping track of its instance. It can thus ensure that no more than one instance is created. This is the singleton pattern.

51 Singleton Pattern Singleton static Instance() SingletonOp() GetSingletonData() static uniqueInstance singletonData return uniqueinstance

52 Singleton Pattern: code class Singleton { public: static Singleton Instance(); } protected: Singleton(); private: Static Singleton _instance // Only one instance can ever be created. // Creation hidden inside Instance().// Cannot access directly.

53 Singleton Pattern: code Singleton _instance; Singleton Instance(){ if (_instance ==null) { _instance=new Singleton; } Return _instance; } // Clients access the singleton // exclusively via the Instance member // function.

54 54 Singleton Pattern  Pros  Controls the number of instances (no need to refer to another class)  Lazy initialization  Cons  Latent coupling between components and singleton  Singleton may have states: hard to test  Cannot extend singleton class  Terrible in multi-thread if not well implemented

55 55 View points  We love singletons (getting weaker and weaker in the past 10 years)  Singletons are evil, actually an anti-pattern (many people believe this)  Use singletons carefully and only when no other alternatives, control the number of singleton classes in your project

56 56 Alternative  Dependency injection:  Create the object at the beginning and pass it as a parameter

57 57 A story from google A new developer go to a group and want to try on some methods testCreditCardCharge() { CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); } This code: Only works when you run as part of the suite. When run in isolation, throws NullPointerException. When you get your credit card bill, you are out $100 for every time the test runs.

58 58 A story from google After a lot of digging, you learn that you need to initialize the CreditCardProcessor. testCreditCardCharge() { CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); } Still not working 

59 59 A story from google After a lot of digging, you learn that you need to initialize the OfflineQueue. testCreditCardCharge() { OfflineQueue.init(); CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); } Still not working 

60 60 A story from google After a lot of digging, you learn that you need to initialize the Database. testCreditCardCharge() { Database.init(); OfflineQueue.init(); CreditCardProcessor.init(); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(100); } But sometimes you have to find out the correct sequence!

61 61 Solution with dependency injection testCreditCardCharge() { Database db = Database(); OfflineQueue q = OfflineQueue(db); CreditCardProcessor ccp = new CreditCardProcessor(q); CreditCard c = new CreditCard( "1234 5678 9012 3456", 5, 2008); c.charge(ccp, 100); }


Download ppt "CS5103 Software Engineering Lecture 09 Software Design and Design Patterns."

Similar presentations


Ads by Google