Refactoring Fest

Post on 06-May-2015

13.971 views 0 download

description

Intent of this tutorial is to provide the participants with a hands-on-experience of real world refactoring by taking an open source project and refactoring it. Benefits After attending this session, the participants should be able to: Build a common vocabulary in the refactoring space Identify code smells Eliminate code smells by applying the simple refactoring techniques explained in Martin Fowler‘s “Refactoring” Write better unit/functional tests for legacy code Understand some of the techniques and pitfalls in refactoring legacy code in the absence of unit and functional tests [”Working effectively with legacy code “] Take existing code and refactor it to standard design patterns [Refactoring to patterns] Learn about the internals of the open source project chosen to refactor Know where to look to continue learning the techniques of refactoring

Transcript of Refactoring Fest

Licensed Under Creative Commons by Naresh Jain

Tutorial Schedule

What, Why, When and How... Refactor?

How to Refactor to Patterns

How to deal with Legacy Code?

Refactoring Hands-on session

2

Licensed Under Creative Commons by Naresh Jain

Three Golden Rules

Once and only once [DRY]

Express intent

Tell, don’t ask

3

Licensed Under Creative Commons by Naresh Jain

Definitions

Loose Usage

Reorganize a program (or something)

As a noun

a change made to the internal structure of some software to make it easier to understand and cheaper to modify, without changing the observable behavior of that software

As a verb

the activity of restructuring software by applying a series of refactorings without changing the observable behavior of that software.

4

Licensed Under Creative Commons by Naresh Jain

What is Refactoring?

A series of small steps, each of which changes the program’s

internal structure without changing its external behavior - Martin Fowler

Verify no change in external behavior by

Testing

Using the right tool - IDE

Formal code analysis by tool

Being very, very careful

5

Licensed Under Creative Commons by Naresh Jain

What if you hear...

We’ll just refactor the code to add logging support

Can you refactor the code so that it authenticates against LDAP instead of Database?

We have too much duplicate code, we need to refactor the code to eliminate duplication

This class is too big, we need to refactor it

Caching?

6

Licensed Under Creative Commons by Naresh Jain

Origin

Ward Cunningham and Kent Beck

Smalltalk style

Ralph Johnson at University of Illinois at Urbana-Champaign

Bill Opdyke’s Thesis

ftp://st.cs.uiuc.edu/pub/papers/refactoring/opdyke-thesis.ps.Z

John Brant and Don Roberts: The Refactoring Browser

7

Licensed Under Creative Commons by Naresh Jain

Why do we Refactor?

Helps us deliver more business value faster

Improves the design of our software

Combat’s “bit rot”

Easier to maintain and understand

Easier to facilitate change

More flexibility

Increased re-usability

8

Licensed Under Creative Commons by Naresh Jain

Why do we Refactor?...

Minimizes technical debt

Keep development at speed

To make the software easier to understand

Write for people, not the compiler

Understand unfamiliar code

To help find bugs

refactor while debugging to clarify the code

To “Fix broken windows” - Pragmatic Programmers

9

Licensed Under Creative Commons by Naresh Jain

ReadabilityWhich code segment is easier to read?

Sample 1

if (date.before(Summer_Start) || date.after(Summer_End)){ charge = quantity * winterRate + winterServiceCharge;else charge = quantity * summerRate;}

Sample 2

if (isSummer(date)) { charge = summerCharge(quantity);Else charge = winterCharge(quantity);}

10

Licensed Under Creative Commons by Naresh Jain

When should you refactor?

To add new functionality

refactor existing code until you understand it

refactor the design to make it simple to add

To find bugs

refactor to understand the code

For code reviews

immediate effect of code review

allows for higher level suggestions

Like championship snooker players we are setting ourselves up for

our next shot

11

Licensed Under Creative Commons by Naresh Jain

The Two Hats

Adding Function

Add new capabilities to the system

Adds new tests

Get the test working

Refactoring

Does not add any new featuresDoes not add tests (but may change some)Restructure the code to remove redundancy

Swap frequently between the hats, but only wear one at a time

12

Licensed Under Creative Commons by Naresh Jain

Refactoring and TDD

TDD Rhythm - Test, Code, Refactor

Add a Test

Run the Test

Make a little change

Run the Test

Refactor

Fail

Pass

Fail

Pass

13

Licensed Under Creative Commons by Naresh Jain

Team Techniques

Encourage refactoring culture

nobody gets things right first time

nobody can write clear code without reviews

refactoring is forward progress

14

Licensed Under Creative Commons by Naresh Jain

Team Techniques...

Provide sound testing base

tests are essential for refactoring

build system and run tests daily

Pair Programming

two programmers working together can be quicker than working separately

refactor with the class writer and a class user

15

Licensed Under Creative Commons by Naresh Jain

How do we Refactor?

We looks for Code-Smells

Things that we suspect are not quite right or will cause us severe pain if we do not fix

16

Licensed Under Creative Commons by Naresh Jain

Common Code Smells

The Big Stinkers

Duplicated code

Feature Envy

Inappropriate Intimacy

Comments

Long Method

Long Parameter List

Switch Statements

Improper Naming

17

Licensed Under Creative Commons by Naresh Jain

Duplicated Code

There is obvious duplication

Such as copy and paste

There are unobvious duplications

Such as parallel inheritance hierarchies.

Similar algorithms

Remedies

Extract Method

Pull Up Field

18

Licensed Under Creative Commons by Naresh Jain

Feature Envy

A method that seems more interested in some other class than the one it is in.

Remedies:

Move Method

Extract Method

19

Licensed Under Creative Commons by Naresh Jain

Extract Methodvoid printOwning(double amount){

printBanner();

// print detailsSystem.Console.WriteLine(string.Format(“name: “, name);System.Console.WriteLine(string.Format(“amount: “, amount);

}

void printOwning(double amount){printBanner();printDetails(amount);

}

void printDetails(double amount){System.Console.WriteLine(string.Format(“name: “, name);System.Console.WriteLine(string.Format(“amount: “, amount);

}

20

Licensed Under Creative Commons by Naresh Jain

Inappropriate Intimacy

Two or more classes fiddling with each other’s private parts.

Remedies

Move Method and Move Field

Change Bi-directional Association to Unidirectional

Extract Class

21

Licensed Under Creative Commons by Naresh Jain

Extract Class

PersonnameofficeAreaCodeofficeNumber

getTelephoneNumber

TelephoneNumber

areaCodenumber

getTelephoneNumber

Person

nametelephoneNumber

getTelephoneNumber

22

Licensed Under Creative Commons by Naresh Jain

Comments

Comments – be suspicious!

Comments are a deodorant.

Comments represent a failure to express an idea in the code.

Remedies:

Extract Method

Rename Method

Introduce Assertion

23

Licensed Under Creative Commons by Naresh Jain

Introduce Assertiondouble GetExpenseLimit() { // should have either expense limit or a primary project return(_expenseLimit != NULL_EXPENSE) ? _expenseLimit : _primaryProject.GetMemberExpenseLimit();}

double GetExpenseLimit() {assert(_expenseLimit != NULL_EXPENSE || _primaryProject != null, “Expense Limit and Primary Project must not be null”);

return(_expenseLimit != NULL_EXPENSE) ? _expenseLimit : _primaryProject.GetMemberExpenseLimit();}

24

Licensed Under Creative Commons by Naresh Jain

Long Method

Good OO code is easiest to understand and maintain with shorter methods with good names

Long methods tend to be harder to read and understand

Remedies:

Extract Method

Replace Temp with Query

Replace Method with Method Object.

Decompose Conditional

25

Licensed Under Creative Commons by Naresh Jain

Replace Temp with Query

double basePrice = _quanity * _itemPrice;

if(basePrice > 1000){

return basePrice * 0.95;}else{ return basePrice * 0.98; }

if(getBasePrice() > 1000) {return getBasePrice() * 0.95;

}else { return getBasePrice() * 0.98; }

double getBasePrice() { return _quanitiy * _itemPrice;}

26

Licensed Under Creative Commons by Naresh Jain

Long parameter list

Functions should have as few parameters as possible.

Remedies:

Replace Parameter with Method

Preserve Whole Object

Introduce Parameter Object

27

Licensed Under Creative Commons by Naresh Jain

Introduce Parameter Object

Customer

AmoutInvoicedIn(Date start, Date end)AmoutRecivedIn(Date start, Date end)AmoutOverdueIn(Date start, Date end)

Customer

AmoutInvoicedIn(DateRange range)AmoutRecivedIn(DateRange range)AmoutOverdueIn(DateRange range)

28

Licensed Under Creative Commons by Naresh Jain

Switch Statements

Type cases are evil because they tend to be duplicated many times.

Remedies:

Replace Type Code with Subclasses

Replace Type Code with State / Strategy

Replace Conditional with Polymorphism.

Replace Parameter with Explicit Methods

Introduce Null Object.

29

Licensed Under Creative Commons by Naresh Jain

Replace Parameter with Explicit Methods

void SetValue(String name, int value){

if(name.Equals(“height”)) {

_height = value; return;}if(name.Equals(“width”)){ _width = value; return;}Trace.Assert(false, “Should never reach here”);

}

void SetHeight(int value){

_height = value;}

void SetWidth(int value){

_width = value;}

30

Licensed Under Creative Commons by Naresh Jain

Inappropriate NamingNames given to variables (fields) and methods should be clear and meaningful.

A variable name should say exactly what it is.

Which is better?

private string s; OR private string salary;

A method should say exactly what it does.

Which is better?

public double calc (double s)

public double calculateFederalTaxes (double salary)

31

Licensed Under Creative Commons by Naresh Jain

Refactoring & Patterns

There is a natural relation between patterns and refactorings. Patterns are where you want to be; refactorings are ways to get there from somewhere else. - Martin Fowler

32

Licensed Under Creative Commons by Naresh Jain

Refactoring to Patterns

Creation – creation of objects

Simplification – code simplification

Generalization – code abstraction

Protection – improve protection of existing code

Accumulation – information accumulation code

Utilities – misc

33

Licensed Under Creative Commons by Naresh Jain

How to refactor Legacy Code?

Identify change points

Find an inflection point

Cover the inflection point

Break external dependencies

Break internal dependencies

Write tests

Make changes

Refactor the covered code.

34

Licensed Under Creative Commons by Naresh Jain

Refactoring Hands-on

We’ll use an open source project to apply refactoring lessons

Make sure your laptops are setup with the project

Form pairs and each pair picks up a module/package of the open source project.

36

Licensed Under Creative Commons by Naresh Jain

Refactoring Hands-on...

You will be introduced to 2-3 code smells at a time

Apply lessons form working with legacy code to write tests around your inflection point

Apply lessons from refactoring and refactoring to patterns to eradicate the code smells

Repeat last 3 steps, till we run out of time

37