Achieving Design Agility by Refactoring Design Smells

Achieving Design Agility by Refactoring Design Smells

This workshop starts with illustration to “Design agility” and highlight the commonly perceived ignorance in current practices associated with design agility. The workshop extensively covers design smells, its classification and catalog, and a series of examples of smells and their impact on software quality. The workshop engages the participants in an exercise to let participants identify smells and their corresponding refactorings.

16a26342d4ff4724dfe59b0dc947dead?s=128

Tushar Sharma

August 02, 2016
Tweet

Transcript

  1. Achieving Design Agility by Refactoring Design Smells Tushar Sharma @Sharma__Tushar

    16 - 17 June 2016, London, UK
  2. Tushar Sharma Researcher@AUEB Earlier, Siemens Research (Bangalore). Interests: Software design

    and architecture, software quality, smells, refactoring, technical debt, and infrastructure as code. http://www.tusharma.in @Sharma__Tushar
  3. A B C D PART-B • Exercise PART-C • Design

    smell catalog • Design smells with examples PART-D • Tools to repay the debt PART-A • Design Agility • Importance of Software Design • Technical Debt • Design Smells
  4. Agile Agile Agile Agile Agile

  5. Let us understand this statement “We are following Agile!”

  6. None
  7. None
  8. Agile is not only about a process!! Agile is all

    about achieving “Agility”. transforms Agile Process Artifacts Mind-set enables Speed Agility
  9. “Agility is the ability to both create and respond to

    change.” -Jim Highsmith “Design Agility” is the ability of the design to respond to change quickly and swiftly.
  10. “Agility is an infinite uphill journey.”

  11. Let us connect the dots Agility Agile should facilitate Speed

    enables Smells reduces Refactoring improves
  12. Capers Jones on design errors in industrial software * http://sqgne.org/presentations/2012-13/Jones-Sep-2012.pdf

    Industry Data on Defect Origins Percentage Contribution 0 25 50 75 100 Requirements Errors Design Errors Coding Errors Bad Fixes Documentation Errors Adminstrative Errors Up to 64% of software defects can be traced back to errors in software design in enterprise software!
  13. Software Quality Technical Debt Design Quality IMPACTS Why care about

    design quality? INDICATES Poor Design Quality means changeability, extensibility, understandability, reusability, ...
  14. Technical Debt (by Jim Highsmith)

  15. What constitutes technical debt? … Code debt Static analysis tool

    violations Inconsistent coding style Design debt Design smells Violations of design rules Test debt Lack of tests Inadequate test coverage Documentation debt No documentation for important concerns Outdated documentation
  16. “Design smells are certain structures in the design that indicate

    violation of fundamental design principles and negatively impact design quality.” Design Smell
  17. Why care about smells? Impacted Quality ▪ Reusability ▪ Changeability

    ▪ Understandability ▪ Extensibility ▪ … Product Quality Design Quality Design Smells Impacted Quality ▪ Maintainability: Affected by changeability & extensibility ▪ Reliability: Impacted by poor understandability ▪ … Indicators ▪ Rigidity & Fragility ▪ Immobility & Opacity ▪ Needless complexity ▪ Needless repetition ▪ …
  18. A B C D PART-B • Exercise PART-C • Design

    smell catalog • Design smells with examples PART-D • Tools to repay the debt PART-A • Design Agility • Importance of Software Design • Technical Debt • Design Smells
  19. A B C D PART-B • Exercise PART-C • Design

    smell catalog • Design smells with examples PART-D • Tools to repay the debt PART-A • Design Agility • Importance of Software Design • Technical Debt • Design Smells
  20. None
  21. The Principle of Abstraction

  22. Enabling techniques for abstraction

  23. What’s that smell?

  24. Scanner PublicScanner Eclipse JDT Clone size of ~3500 LOC

  25. Duplicate abstraction This smell arises when two or more abstractions

    have identical names or identical implementation or both.
  26. None
  27. Let us refactor the smell Change name of one of

    the abstractions Factor out the commonality into a third abstraction which can be used by the original abstraction Remove a duplication from one of the abstractions which then refers to the other abstraction for that particular functionality
  28. 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 } What’s that smell?
  29. Missing abstraction This smell arises when clumps of data or

    encoded strings are used instead of creating a class or an interface.
  30. Let us refactor the smell 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(); } 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 }
  31. java.util.Calendar In addition to methods supporting dates, the class has

    methods for supporting time as well! What’s that smell?
  32. Multi-faceted abstraction This smell arises when an abstraction has more

    than one responsibility assigned to it.
  33. Let us refactor the smell

  34. None
  35. The principle of encapsulation

  36. Enabling techniques for encapsulation

  37. What’s that smell?

  38. Deficient encapsulation This design smell occurs when the declared accessibility

    of one or more members of an abstraction is more permissive than actually required.
  39. What’s that smell?

  40. What’s that smell?

  41. Missing encapsulation This smell occurs when implementation variations are not

    encapsulated within an abstraction or hierarchy.
  42. Let us refactor the smell

  43. Let us refactor the smell

  44. None
  45. The principle of modularization

  46. Enabling techniques for modularization

  47. What’s that smell?

  48. Broken modularization This smell arises when members of an abstraction

    are broken and spread across multiple abstractions (when ideally they should have been localized into a single abstraction). Two forms of this smell: Data and methods that ideally belong to an abstraction are split among two or more abstractions. Methods in a class that are interested in members of other classes.
  49. Let us refactor the smell

  50. Let us refactor the smell

  51. What’s that smell?

  52. Insufficient modularization This smell arises when an abstraction exists that

    has not been completely decomposed and a further decomposition could reduce its size, implementation complexity, or both. There are two forms of this smell - • Bloated interface • Bloated implementation
  53. Example The abstract class java.awt.Component is an example of insufficient

    modularization It is a massive class with 332 methods (of which 259 are public!) 11 nested/inner classes 107 fields (including constants) source file spans 10,102 lines of code!
  54. Let us refactor the smell Refactoring for ‘bloated interface’ Extract-class

    Client specific interfaces Refactoring for ‘bloated implementation’ Extract-method => private helper methods Extract-class or Move-field/Move-method to encapsulate each responsibility within separate (new or existing) abstractions.
  55. None
  56. The principle of hierarchy

  57. Enabling techniques for hierarchy

  58. What’s that smell?

  59. Unnecessary hierarchy This smell arises when the whole inheritance hierarchy

    is unnecessary, indicating that inheritance has been applied needlessly for the particular design context.
  60. Let us refactor the smell

  61. Let us refactor the smell

  62. What’s that smell?

  63. Rebellious hierarchy This smell arises when a subtype rejects the

    methods provided by its supertype(s): throw an exception, provide an empty (or NOP i.e., NO Operation) method provide a method definition that just prints “should not implement” message
  64. Let us refactor the smell

  65. Let us refactor the smell

  66. Let us refactor the smell

  67. What’s that smell?

  68. What’s that smell?

  69. Broken hierarchy This smell arises when a supertype and its

    subtype conceptually do not share an “IS- A” relationship resulting in broken substitutability.
  70. Let us refactor the smell

  71. Let us refactor the smell

  72. A B C D PART-B • Exercise PART-C • Design

    smell catalog • Design smells with examples PART-D • Tools to repay the debt PART-A • Design Agility • Importance of Software Design • Technical Debt • Design Smells
  73. Tools Comprehension tools Imagix 4D, Structure 101 Critique, code-clone detectors,

    and metric tools Infusion, Designite, Ndepend Simian, CPD Understand, Source-monitor, Designite Technical debt quantification and visualization tools SonarQube Refactoring tools Refactoring inferencing tools – SCOUT, Jdeoderant Refactoring performing tools – Eclipse, Resharper
  74. http://www.designite-tools.com

  75. http://www.designite-tools.com

  76. Key takeaways

  77. Suggested Reading

  78. None
  79. Thank you! Tushar Sharma Twitter@Sharma__Tushar tusharsharma@ieee.org