Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Applying Design Principles in Practice

8,342 views

Published on

The tutorial titled "Applying design principles in practice" was presented in ISEC (India Software Engg Conference) on 18th Feb 2015 in Bengaluru by Tushar Sharma, Ganesh Samarthyam, and Girish Suryanarayana.

Published in: Software
  • Login to see the comments

Applying Design Principles in Practice

  1. 1. Applying Design Principles in Practice Tushar Sharma Ganesh Samarthyam Girish Suryanarayana
  2. 2. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  3. 3. Why care about design quality and design principles?
  4. 4. Poor software quality costs more than $150 billion per year in U.S. and greater than $500 billion per year worldwide - Capers Jones
  5. 5. The city metaphor Source: http://indiatransportportal.com/wp-content/uploads/2012/04/Traffic-congestion1.jpg
  6. 6. “Applying design principles is the key to creating high-quality software!” Architectural principles: Axis, symmetry, rhythm, datum, hierarchy, transformation
  7. 7. What do we mean by “principles”? “Design principles are key notions considered fundamental to many different software design approaches and concepts.” - SWEBOK ‘04
  8. 8. "The critical design tool for software development is a mind well educated in design principles" - Craig Larman
  9. 9. Fundamental Design Principles
  10. 10. SOLID principles •  There&should&never&be&more&than&one&reason&for&a&class&to& change&& Single'Responsibility' Principle'(SRP)' •  So6ware&en88es&(classes,&modules,&func8ons,&etc.)&should& be&open&for&extension,&but&closed&for&modifica8on& Open'Closed'Principle' (OCP)' •  Pointers&or&references&to&base&classes&must&be&able&to&use& objects&of&derived&classes&without&knowing&it& Liskov’s'Subs<tu<on' Principle'(LSP)' •  Depend&on&abstrac8ons,&not&on&concre8ons& Dependency'Inversion' Principle'(DIP)' •  Many&clientGspecific&interfaces&are&beHer&than&one& generalGpurpose&interface& Interface'Segrega<on' Principle'(ISP)'
  11. 11. 3 principles behind patterns Program to an interface, not to an implementation Favor object composition over inheritance Encapsulate what varies
  12. 12. Booch’s fundamental principles Principles* Abstrac/on* Encapsula/on* Modulariza/on* Hierarchy*
  13. 13. How to apply principles in practice? Abstraction Encapsulation Modularization Hierarchy Code How to bridge the gap?
  14. 14. Real scenario #1 Initial design
  15. 15. Real scenario #1 ❖ How will you refactor such that: ❖ A specific DES, AES, TDES, … can be “plugged” at runtime? ❖ Reuse these algorithms in new contexts? ❖ Easily add support for new algorithms in Encryption? Next change: smelly design
  16. 16. Time to refactor! Three strikes and you refactor Martin Fowler
  17. 17. Potential solution #1? Broken hierarchy!
  18. 18. Potential solution #2? Algorithms not reusable!
  19. 19. Potential solution #3?
  20. 20. Can you identify the pattern?
  21. 21. You’re right: Its Strategy pattern!
  22. 22. Real scenario #2 Initial design
  23. 23. Real scenario #2 How to add support for new content types and/or algorithms?
  24. 24. How about this solution?
  25. 25. Can you identify the pattern structure?
  26. 26. You’re right: Its Bridge pattern structure!
  27. 27. Wait, what principle did we apply?
  28. 28. Open Closed Principle (OCP) Bertrand Meyer Software entities should be open for extension, but closed for modification
  29. 29. Variation Encapsulation Principle (VEP) Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides Encapsulate the concept that varies
  30. 30. Fundamental principle: Encapsulation The principle of encapsulation advocates separation of concerns and information hiding through techniques such as hiding implementation details of abstractions and hiding variations
  31. 31. Enabling techniques for encapsulation
  32. 32. Design principles and enabling techniques
  33. 33. What is refactoring? Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior
  34. 34. Applying principles in practice Encapsulation Violating encapsulation Adherence to encapsulation Enabling technique: Hide variations
  35. 35. Applying principles in practice Principle Violating principles Adherence to principles Refactoring Bad design (with smells) Good design (with patterns)
  36. 36. Design determines qualities Understandability Changeability Extensibility Reusability Testability Reliability DESIGN impacts impacts impacts
  37. 37. Smells approach to learn principles A"good"designer"is" one"who"knows"the" design"solu1ons" A"GREAT"designer"is" one"who"understands" the"impact"of"design" smells"and"knows" how"to"address"them!
  38. 38. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  39. 39. What is abstraction?
  40. 40. public'class'Throwable'{' //'following'method'is'available'from'Java'1.0'version.'' //'Prints'the'stack'trace'as'a'string'to'standard'output'' //'for'processing'a'stack'trace,'' //'we'need'to'write'regular'expressions'' public'void'printStackTrace();'''''' //'other'methods'elided'' }'
  41. 41. Refactoring for this smell public'class'Throwable'{' //'following'method'is'available'from'Java'1.0'version.'' //'Prints'the'stack'trace'as'a'string'to'standard'output'' //'for'processing'a'stack'trace,'' //'we'need'to'write'regular'expressions'' public'void'printStackTrace();'''''' //'other'methods'elided'' }' public'class'Throwable'{' public'void'printStackTrace();'''''' ''''''''''''public'StackTraceElement[]'getStackTrace();'//'Since'1.4' '''''''''''''//'other'methods'elided'' }' public'final'class'StackTraceElement'{' public'String'getFileName();' public'int'getLineNumber();' public'String'getClassName();' public'String'getMethodName();' public'boolean'isNativeMethod();' }'
  42. 42. Applying abstraction principle Provide a crisp conceptual boundary and a unique identity
  43. 43. public class FormattableFlags {     // Explicit instantiation of this class is prohibited.     private FormattableFlags() {}     /** Left-justifies the output.  */     public static final int LEFT_JUSTIFY = 1<<0; // '-'     /** Converts the output to upper case */     public static final int UPPERCASE = 1<<1;    // 'S'     /**Requires the output to use an alternate form. */     public static final int ALTERNATE = 1<<2;    // '#' }
  44. 44. class Currency { public static String DOLLAR = "u0024"; public static String EURO = "u20AC"; public static String RUPEE = "u20B9"; public static String YEN = "u00A5"; // no other members in this class }
  45. 45. Applying abstraction principle Assign single and meaningful responsibility
  46. 46. Enabling techniques for abstraction
  47. 47. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  48. 48. What is encapsulation?
  49. 49. Refactoring for that smell
  50. 50. Applying encapsulation principle Hide implementation details
  51. 51. Scenario Initial design TextView + Draw() BorderedTextView + Draw() + DrawBorder()
  52. 52. Real scenario Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  53. 53. Supporting new requirements Revised design with new requirements TextView + Draw() BorderedTextView + Draw() + DrawBorder() ScrollableTextView ScrollableBordered TextView - borderWidth + Draw() + ScrollTo() - ScrollPosition + Draw() + ScrollTo() + DrawBorder() - ScrollPosition - borderWidth
  54. 54. Real scenario ❖ How will you refactor such that: ❖ You don't have to “multiply- out” sub-types? (i.e., avoid “explosion of classes”) ❖ Add or remove responsibilities (e.g., scrolling) at runtime? Next change: smelly design
  55. 55. How about this solution? VisualComponent + Draw() TextView + Draw() ScrollDecortor BorderDecorator + Draw() + ScrollTo() - ScrollPosition + Draw() + DrawBorder() - borderWidth Decorator + Draw() component->Draw() Decorator::Draw() DrawBorder() Decorator::Draw() ScrollTo() Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  56. 56. At runtime (object diagram) Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  57. 57. Can you identify the pattern? VisualComponent + Draw() TextView + Draw() ScrollDecortor BorderDecorator + Draw() + ScrollTo() - ScrollPosition + Draw() + DrawBorder() - borderWidth Decorator + Draw() component->Draw() Decorator::Draw() DrawBorder() Decorator::Draw() ScrollTo() Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  58. 58. You’re right: Its Decorator pattern! Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  59. 59. Decorator pattern: Discussion ❖ Want to add responsibilities to individual objects (not an entire class) ❖ One way is to use inheritance ❖ Inflexible; static choice ❖ Hard to add and remove responsibilities dynamically Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality ❖ Add responsibilities through decoration ❖ in a way transparent to the clients ❖ Decorator forwards the requests to the contained component to perform additional actions ❖ Can nest recursively ❖ Can add an unlimited number of responsibilities dynamically
  60. 60. Identify pattern used in this code LineNumberReader lnr = new LineNumberReader( new BufferedReader( new FileReader(“./test.c"))); String str = null; while((str = lnr.readLine()) != null) System.out.println(lnr.getLineNumber() + ": " + str);
  61. 61. Decorator pattern in Reader
  62. 62. Scenario a) How do we treat files and folders alike? b) How can we handle shortcuts? File + GetName() + GetSize() + … - name: String - size: int - type: FileType - data: char[] - … Folder + GetName() + GetFiles() + GetFolders() + … - name: String - files[]: File - folders[]: Folder
  63. 63. How about this solution? FileItem + GetName() + GetSize() + Add(FileItem) + Remove(FileItem) Folder + GetFiles() + … File - files: FileItem + GetType() + GetContents() + … - type: FileType - data: char[] Shortcut + GetLinkedFileItem() + … - linkToFile: FileItem
  64. 64. Composite pattern Source: “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Addison-Wesley,1994
  65. 65. Composite pattern: Discussion ❖ There are many situations where a group of components form larger components ❖ Simplistic approach: Make container component contain primitive ones ❖ Problem: Code has to treat container and primitive components differently Compose objects into tree structures to represent part-whole hierarchies. Composite lets client treat individual objects and compositions of objects uniformly. ❖ Perform recursive composition of components ❖ Clients don’t have to treat container and primitive components differently
  66. 66. Decorator vs. Composite Decorator and composite structure looks similar: Decorator is a degenerate form of Composite! Decorator Composite At max. one component Can have many components Adds responsibilities Aggregates objects Does not make sense to have methods such as Add(), Remove(), GetChid() etc. Has methods such as Add(), Remove(), GetChild(), etc.
  67. 67. Applying encapsulation principle Hide variations
  68. 68. Enabling techniques for encapsulation
  69. 69. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  70. 70. What is modularization?
  71. 71. Refactoring for this smell
  72. 72. Applying modularisation principle Localize related data and methods
  73. 73. Suggested refactoring for this smell
  74. 74. Applying modularisation principle Create acyclic dependencies
  75. 75. Enabling techniques for modularisation
  76. 76. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  77. 77. What is hierarchy?
  78. 78. public Insets getBorderInsets(Component c, Insets insets){ Insets margin = null; // Ideally we'd have an interface defined for classes which // support margins (to avoid this hackery), but we've // decided against it for simplicity // if (c instanceof AbstractButton) { margin = ((AbstractButton)c).getMargin(); } else if (c instanceof JToolBar) { margin = ((JToolBar)c).getMargin(); } else if (c instanceof JTextComponent) { margin = ((JTextComponent)c).getMargin(); } // rest of the code elided …
  79. 79. Suggested refactoring for this smell
  80. 80. Suggested refactoring for the code margin = c.getMargin(); if (c instanceof AbstractButton) { margin = ((AbstractButton)c).getMargin(); } else if (c instanceof JToolBar) { margin = ((JToolBar)c).getMargin(); } else if (c instanceof JTextComponent) { margin = ((JTextComponent)c).getMargin(); }
  81. 81. Applying hierarchy principle Apply meaningful classification
  82. 82. Suggested refactoring for this smell
  83. 83. A real-world case study
  84. 84. Applying hierarchy principle Ensure proper ordering
  85. 85. Enabling techniques for hierarchy
  86. 86. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  87. 87. How to repay technical debt in practice?
  88. 88. IMPACT process model
  89. 89. Useful tools during Refactoring
  90. 90. Comprehension Tools STAN http://stan4j.com
  91. 91. Comprehension Tools Code City http://www.inf.usi.ch/phd/wettel/codecity.html
  92. 92. Comprehension Tools Imagix 4D http://www.imagix.com
  93. 93. Critique, code-clone detectors, and metric tools Infusion www.intooitus.com/products/infusion
  94. 94. Critique, code-clone detectors, and metric tools Designite www.designite-tools.com
  95. 95. Critique, code-clone detectors, and metric tools PMD Copy Paste Detector (CPD) http://pmd.sourceforge.net/pmd-4.3.0/cpd.html
  96. 96. Critique, code-clone detectors, and metric tools Understand https://scitools.com
  97. 97. Technical Debt quantification/visualization tools Sonarqube http://www.sonarqube.org
  98. 98. Refactoring tools ReSharper https://www.jetbrains.com/resharper/features/
  99. 99. Agenda • Introduction • Applying abstraction • Applying encapsulation • Applying modularisation • Applying hierarchy • Practical considerations • Wrap-up
  100. 100. Principles and enabling techniques
  101. 101. “Applying design principles is the key to creating high-quality software!” Architectural principles: Axis, symmetry, rhythm, datum, hierarchy, transformation
  102. 102. ganesh.samarthyam@gmail.com @GSamarthyam tusharsharma@ieee.org @Sharma__Tushar girish.suryanarayana@siemens.com @Girish_Sur www.designsmells.com @designsmells

×