introduction to refactoring jim cooper falafel software

Post on 05-Jan-2016

234 Views

Category:

Documents

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Introduction to Refactoring

Jim Cooper

Falafel Software

Refactoring

Refactoring. Improving the Design of Existing Code

Martin Fowler

2000, Addison-Wesley

ISBN 0-201-48567-2

We will use that terminology, guidelines and naming

What is Refactoring?

“Refactoring is the process of changing a software system in such a way that it does not

alter the external behaviour of the code yet improves its internal structure.”

Term applies both to the process and the individual techniques

What is Refactoring? - 2

Each refactoring is a series of steps

Each step is simple and small

Minimises introduction of new bugs

Unit tests used to verify changes

Behavioural changes to a program are not refactorings

Why Refactor?

Code is not for computers to read, it’s for us to read

90% of the lifetime of most software is in maintenance mode

Source code must be easy for humans to read, understand and modify

Refactoring helps make the code more usable by programmers

Aims of Refactoring

Improved design

Make code easier to understand

Can use it on other people’s code

Help find bugs

Faster programming in the long term

Formalise and name best practices

Easier to talk about

Reduce chaos in long-lived code

Opportunities for Refactoring

When adding functionality

Make adding new feature easier

Keep refactoring separate, though

When fixing a bug

During a code review

Pair programming

Refactoring takes time

Sneak it past managers

Refactoring Techniques

Too many to look at all of them

Will not discuss unit testing in detail

Start with the main ones, and then browse the book looking at others

No need to read the book cover to cover (it’s not that interesting)

Points to Note

Refactoring relies heavily on having object oriented code

Refactorings are usually more atomic than patterns, but some use patterns

Often language dependent

Refactoring book is very Java oriented

We will cover converting to Delphi

Not many refactorings use interfaces

Points to Note - 2

Many refactorings make use of other, simpler refactorings

Some are opposites

Use the one that makes your code easier to understand

Can apply some mechanically

It is possible to go too far!

Extract Method

Probably the most used technique

You should have done this many times yourself

Identify code to reuse, or that is making a method too long, so we make a new method out of it

Difference here is the formal definition of the process, and the guidelines for its use

Structure of Extract Method

Name – Extract Method

Summary – describes when to use

You have a code fragment that can be grouped together

Turn the fragment into a method whose name explains the purpose of the method

Structure of Extract Method - 2

Short code example

Motivation

Describes why the refactoring should be done, and also when it shouldn’t

Mechanics

Step by step instructions

One or more longer examples, usually with discussion

Structure of Extract Method - 3

Motivation

A method is too long

A section of code needs a comment to explain it

Short (well-named) methods easier to reuse and override

Higher-level methods easier to read

Good naming is key

Structure of Extract Method - 4

Mechanics

Create a new method with a good name

Copy extracted code to new method

Deal with variables and parameters in the original method

Dealing with Variables

Local variables only used in the extracted code can be copied to the new method

One original variable modified

Make the new method a function

Several original variables modified

Use var parameters

Use other refactorings first

Dealing with Variables - 2

Replace Temp with Query

Remove local variable, move expression to a method and call it each time the variable was used

Split Temporary Variable

Use a different local variable for each assignment

Structure of Extract Method - 5

Pass any original parameters used to the new method

Compile

Replace extracted code with method call

Remove any local variables no longer used

Compile and test

Don’t forget to test!!

Extract Class

Used when a class is violating the principle of separation of concerns

Often the result of feature creep

Can result from too many Extract Method refactorings

Splits out related subset of data and methods into a new class

May need to rename the old class if its duties have changed

Extract Class - 2

Normally need a reference to an object of the new class in the old one

Leave the new class in the implementation section if only used internally

Uses Move Field and Move Method refactorings to move elements of the new class across (test after each move)

Inline Class

The opposite of Extract Class

Applied when a class is doing too little

Move fields and methods into a class that uses them (there won’t be many)

Fowler humour :

The last step of the refactoring reads “Hold a short, simple funeral service”

Move Method

Moves a method from one class to another

May change name in the new class

Original class probably needs to refer to an instance of the new one

If the method is declared in an ancestor or descendant class, may not be able to move it easily

Inline Temp

Replace a local variable assigned to with a simple expression, with the expression

Removing local variables can make other refactorings easier

Local variable may be doing no harm, or may be there to avoid breaking the Law of Demeter

Leave it there

Rename Method

If the task of a method has changed, rename it to reflect the new duties

Seems trivial, but is very important

Bad naming defeats the whole purpose of encapsulation

Code is confusing, in the worst case it can be completely misinterpreted

Replace Magic Number with Symbolic Constant

Encapsulates a standard piece of programming advice

Applies to strings etc, as well, of course

This sort of refactoring useful when training new programmers

Replace Error Code with Exception

If you don’t already do this, line up at the front for a slapping

Code can be written assuming it works, and is therefore much easier to read

Error handling code separated out

Encapsulate Field

Needs to be modified for Delphi

Replace Field with Property

Replace a public field with a property

Otherwise the Delphi Style Police will come and kick you around

Use the Delphi naming convention

Move field to private, rename with F

Make a property named without the F

Self Encapsulate Field

We might allow direct access to a field within a class, if field is private

If field needs to be protected or better, or has side effects when used, then make it into a property

Direct access in constructor, destructor and property accessor methods

Use Replace Field with Property

Remove Control Flag

Some people use a local variable as a control flag to break out of loops

I’ve even seen goto used this way!

Use Break, Continue and Exit instead

Replace Type Code with State/Strategy

This refactoring introduces either the State or Strategy pattern

Used when the class behaviour varies depending on some state value

Lots of case statements are a giveaway

Demo code

Finite State Machine

This example is from ToD, with the kind permission of Julian Bucknall

Convert Refactorings to Delphi

Use const instead of final

To make an immutable class, make all the properties read only, and set their values in the constructor

Query = Function

Temporary variable = local variable

Some refactorings cannot be applied

e.g. garbage collection

When to Refactor – Bad Smells

Kent Beck’s idea

Combination of experience and intuition sometimes makes us feel code just isn’t right

There are some indicators we can look for

Bad Smells

Have names and recommended treatments

Bad Smells

Duplicated Code

Long Method

Large Class

Long Parameter List

Divergent Change

Shotgun Surgery

Feature Envy

Bad Smells - 2

Data Clumps

Primitive Obsession

Switch Statements

Parallel Inheritance Hierachies

Lazy Class

Speculative Generality

Data Class, Refused Bequest

Comments

Problems

Do not apply refactorings without thought for the consequences

Threads

Discipline is new, so not all problems found yet

Databases

Changing interfaces

Designs difficult to refactor

Code is beyond all help

Miscellaneous

Still need upfront design, but can design for ease of refactoring

Don’t make design too flexible

Don’t make optimisation decisions before finding bottlenecks

Refactor first, optimise after

Tools exist for Java (some in JBuilder) and C#, but little for Delphi ...

Refactoring in Delphi

Until now!

Diamondback has the following refactorings built in, with a promise of many more to follow

Rename

Extract Method

Extract Resource String

Refactoring in Delphi - 2

In addition, the new refactoring engine makes possible some handy things which are not, strictly speaking, refactorings

SyncEdit mode

Find References

Declare Variable

Declare Field

Import Namespace

Questions?

Thank You

You can contact me further atjim@falafelsoft.com

top related