79
Achieving Design Agility by Refactoring Design Smells Tushar Sharma @Sharma__Tushar 16 - 17 June 2016, London, UK

Achieving Design Agility by Refactoring Design Smells

Embed Size (px)

Citation preview

Achieving Design Agilityby Refactoring Design Smells

Tushar Sharma@Sharma__Tushar

16 - 17 June 2016, London, UK

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

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

Agile

Agile

Agile

Agile

Agile

Let us understand this statement

“We are following Agile!”

Agile is not only about a process!!

Agile is all about achieving “Agility”.

transforms

Agile

Process

Artifacts

Mind-set

enablesSpeed

Agi

lity

“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.

“Agility is an infinite uphill journey.”

Let us connect the dots

Agility

Agileshould facilitate

Speedenables

Smells

reduces

Refactoringimproves

Capers Jones on design errors in industrial software

* http://sqgne.org/presentations/2012-13/Jones-Sep-2012.pdf

Industry Data on Defect Origins

Perc

enta

ge C

ontr

ibut

ion

0

25

50

75

100

Requirements ErrorsDesign ErrorsCoding ErrorsBad FixesDocumentation ErrorsAdminstrative Errors

Up to 64% of software defects can be traced back to errors in

software design in enterprise software!

Software Quality

Technical Debt

Design Quality

IMPACTS

Why care about design quality?

INDICATES

Poor

Design Quality means changeability, extensibility,

understandability, reusability, ...

Technical Debt

(by Jim Highsmith)

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

“Design smells are certain structures in the design that indicate violation of fundamental design principles and

negatively impact design quality.”

Design Smell

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 ▪ …

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

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

The Principle of Abstraction

Enabling techniques for abstraction

What’s that smell?

Scanner

PublicScanner

Eclipse JDT

Clone size

of ~3500 LOC

Duplicate abstractionThis smell arises when two or more abstractions have identical names or identical implementation or both.

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

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?

Missing abstraction

This smell arises when clumps of data or encoded strings are used instead of

creating a class or an interface.

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

}

java.util.Calendar

In addition to methods supporting dates, the class has

methods for supporting time as well!

What’s that smell?

Multi-faceted abstraction

This smell arises when an abstraction has more than one responsibility assigned to it.

Let us refactor the smell

The principle of encapsulation

Enabling techniques for encapsulation

What’s that smell?

Deficient encapsulation

This design smell occurs when the declared accessibility of one or

more members of an abstraction is more permissive than actually

required.

What’s that smell?

What’s that smell?

Missing encapsulation

This smell occurs when implementation variations are not encapsulated within an abstraction or hierarchy.

Let us refactor the smell

Let us refactor the smell

The principle of modularization

Enabling techniques for modularization

What’s that smell?

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.

Let us refactor the smell

Let us refactor the smell

What’s that smell?

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

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!  

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.

The principle of hierarchy

Enabling techniques for hierarchy

What’s that smell?

Unnecessary hierarchy

This smell arises when the whole inheritance hierarchy is unnecessary, indicating that inheritance has been applied needlessly for the particular design context.

Let us refactor the smell

Let us refactor the smell

What’s that smell?

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

Let us refactor the smell

Let us refactor the smell

Let us refactor the smell

What’s that smell?

What’s that smell?

Broken hierarchy

This smell arises when a supertype and its subtype conceptually do not share an “IS-

A” relationship resulting in broken substitutability.

Let us refactor the smell

Let us refactor the smell

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

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

http://www.designite-tools.com

http://www.designite-tools.com

Key takeaways

Suggested Reading

Thank you!

Tushar Sharma Twitter@Sharma__Tushar [email protected]