Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Tushar Sharma

August 02, 2016
Tweet

More Decks by Tushar Sharma

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. Agile is not only about a process!! Agile is all

    about achieving “Agility”. transforms Agile Process Artifacts Mind-set enables Speed Agility
  4. “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.
  5. Let us connect the dots Agility Agile should facilitate Speed

    enables Smells reduces Refactoring improves
  6. 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!
  7. Software Quality Technical Debt Design Quality IMPACTS Why care about

    design quality? INDICATES Poor Design Quality means changeability, extensibility, understandability, reusability, ...
  8. 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
  9. “Design smells are certain structures in the design that indicate

    violation of fundamental design principles and negatively impact design quality.” Design Smell
  10. 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 ▪ …
  11. 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
  12. 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
  13. Duplicate abstraction This smell arises when two or more abstractions

    have identical names or identical implementation or both.
  14. 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
  15. 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?
  16. Missing abstraction This smell arises when clumps of data or

    encoded strings are used instead of creating a class or an interface.
  17. 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 }
  18. java.util.Calendar In addition to methods supporting dates, the class has

    methods for supporting time as well! What’s that smell?
  19. Deficient encapsulation This design smell occurs when the declared accessibility

    of one or more members of an abstraction is more permissive than actually required.
  20. 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.
  21. 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
  22. 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!
  23. 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.
  24. Unnecessary hierarchy This smell arises when the whole inheritance hierarchy

    is unnecessary, indicating that inheritance has been applied needlessly for the particular design context.
  25. 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
  26. Broken hierarchy This smell arises when a supertype and its

    subtype conceptually do not share an “IS- A” relationship resulting in broken substitutability.
  27. 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
  28. 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