What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

32
What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD

Transcript of What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Page 1: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

What is Refactoring?

CSE301

University of Sunderland

Harry R. Erwin, PhD

Page 2: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Purpose

• The purpose of this lecture is to introduce a way of cleaning up working code.

• This is called refactoring and is part of current industry practice.

• You are expected to experiment with it inyour PBL projects.

• This lecture is organised to structure your investigation of refactoring. You will need to do some reading in the sources.

Page 3: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Sources

• Fowler, 2000, Refactoring: Improving the Design of Existing Code, Addison-Wesley. Available electronically at the library.

• http://www.amazon.com/exec/obidos/tg/detail/-/0321109295/103-4060125-0311065

• http://www.amazon.com/exec/obidos/ASIN/0130648841/103-4060125-0311065

• http://www.refactoring.com/catalog/ • http://www.win.ua.ac.be/~lore/refactoringProject/index.php • Extensive discussions on the comp.object newsgroup.

Page 4: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Topics

• Test-Driven Development

• JUnit

• Refactoring– Principles– Bad Smells in Code– A Catalogue of Refactorings

Page 5: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Test-Driven Development

• Refactoring depends on having good unit tests. This means you need to be doing test-driven development.

• Test-driven development is a method of software development where tests specify interfaces of implementation and all code must have passed the tests. (Wikipedia)

Page 6: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

How Bob Martin Describes TDD (personal communication)

Erwin: TDD as I understand it:1. Write a test for a bit of functionality.2. Show that it fails.3. Write the code to make the test pass.Martin: A good summary, but there's more. 1. We do not write production code until there is a failing test.2. We write the simplest possible production code to get the test to

pass.3. We do not write more tests when we have a failing test.

4. We do not add to a failing test.

Page 7: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Martin Comments Further

• If you watched someone doing TDD you would see them oscillating between test code and production code once every minute or so.

• During each oscillation the programmer would add a few lines to his test code, thus making it fail (or not compile) and then add just a few lines to his production code in order to make the test pass (or compile).

• Each oscillation is so simple that it's not worth taking. • Each oscillation is so simple that the risk of error is close to zero. • If you walk into a room of people working this way, and chose

anyone at random, a minute ago all his code would have been working.

Page 8: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Refactoring

• Deals with code rot. Your program works but it has become ugly as it has been modified.

• “Refactoring is a technique to restructure code in a disciplined way. For a long time it was a piece of programmer lore, done with varying degrees of discipline by experienced developers, but not passed on in a coherent way.” (Fowler)

• Will be very useful for your projects.

Page 9: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Refactoring Principles

• Change only the implementations• Use it to improve the design of software• Use it to make software more

understandable• Use it to help find bugs• Use it to help you program faster• Use it to prepare your current program for

modification.

Page 10: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

When?

• “Three strikes and you refactor.”– The third time you have to cope with something

ugly, fix it.

particularly…– When you add functionality– When you need to fix a bug– When you do a code review

Page 11: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Problems with Refactoring

• The Manager (expectation management)• Overuse (spinning your wheels)• Databases (database schemas are rigid!)• Public Interfaces (avoid changing things the

user depends on)• A Design that Commits You (In ham and

eggs, the hen is involved; the pig is committed. Don’t go there.)

Page 12: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

How Software May “Smell”:

• The system is rigid—it’s hard to change because everything has to change at once.

• The system is fragile—changes cause the system to break in the strangest of places.

• The system is immobile—that is, not reusable.• The system is viscous—doing things the right way is hard.• The system is needlessly complex.• The system contains mindless repetition.• The system is opaque—hard to understand.Have you ever seen software with these problems?

Page 13: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

What “Bad Smells” Smell Like

• Duplicated Code—cut and pasted everywhere

• Long Method—hard to understand

• Long Parameter List—multi-line calls

• Parallel Inheritance—two hierarchies ‘joined at the hip’

• Divergent Change—violates the Single Responsibility Principle.

• Shotgun Surgery—can’t change just one thing

• Feature Envy—a class needs lots of methods from another class.

• Data Clumps—data always used together

• Large Class—everything including kitchen sink

• Primitive Obsession—procedural coding style

• Switch Statements—and duplicated cases

Page 14: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

More “Bad Smells” (in Code)

• Lazy Class—does no useful work• Speculative Generality—hooks that are never used• Temporary Field—variables only used sometimes• Message Chains—reference to a reference to a ref…• Middle Man—everything is delegated to a second class• Inappropriate Intimacy—’friends’• Alternative Classes/Different Interfaces• Incomplete Library Class—lacks useful methods• Data Class—hold data, nothing else• Refused Bequest—inherited methods ignored• Comments—as deodorants

Page 15: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

The Basic Rule of Refactoring

• “Refactor the low hanging fruit” http://c2.com/cgi/wiki?RefactorLowHangingFruit

• Low Hanging Fruit (def): “The thing that gets you most value for the least investment.”

• In other words, don’t spend much time on it. There are always ways to improve any design incrementally. We will explore a few of them.

Page 16: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

The Goal of Refactoring

• To improve code without changing what it does.

• This in some ways is similar to how an optimizing compiler restructures code.

• Eclipse automates many of these actions.

• Think about why they work!

Page 17: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

A Catalog of Refactorings

1. Composing Methods

2. Moving Features Between Objects

3. Organizing Data

4. Simplifying Conditionals

5. Making Method Calls Simpler

6. Generalization

7. Big Refactorings

Page 18: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

1. Composing Methods

• Extract Method• Inline Method• Inline Temp• Replace Temp with Query• Introduce Explaining Variable• Split Temporary Variable• Remove Assignments to Parameters• Replace Method with Method Object• Substitute Algorithm

Page 19: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• Extract Method is the most important, since it takes a clump of code and makes it into a small method. Eclipse handles this very well. It has problems with local variables, so some of the specialized methods handle those. I use this a lot.

• Inline Method is the reverse method. Use it if Extract Method creates ugly code.

• Replace Method with Method Object moves local variables of a method into the class fields of a ‘functor’ class, so Extract Method can be used more easily.

Page 20: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

2. Moving Features Between Objects

• Move Method• Move Field• Extract Class• Inline Class• Hide Delegate• Remove Middle Man• Introduce Foreign Method• Introduce Local Extension

Page 21: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• Remember CRC cards?• You never get responsibilities right the first time.

This is how you change your mind.• If you need to move functions between objects,

these refactorings handle it. Move Method, Move Field, Extract Class, and Inline Class are the heavyweights here.

• The remainder are special purpose methods to support the Big Four.

Page 22: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

3. Organizing Data

• Self Encapsulate Field

• Replace Data Value with Object

• Change Value to Ref

• Change Ref to Value

• Replace Array with Object

• Duplicate Observed Data

• Switch Uni/Bidirectional Association

• Replace Magic Number

• Encapsulate Field

• Encapsulate Collection

• Replace Record

• Replace Type Code with Class/Subclass/ State/Strategy

• Replace Subclass with Fields

Page 23: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• These generally clean up problems with how classes define and access fields. I use encapsulate field a lot.

• A common need in student projects.• Value objects are immutable objects that are equal if

their fields are equal—you have to override equals() and hashCode() for them.

• The most advanced refactoring here is probably Duplicate Observed Data. That’s how you fix a design that mixes model or business logic with GUI or SQL code.

Page 24: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

4. Simplifying Conditionals

• Decompose it• Consolidate it• Consolidate Duplicate Fragments• Remove Control Flag• Replace Nested Conditional with Guard Clauses• Replace with Polymorphism• Introduce Null Object• Introduce Assertion

Page 25: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• Involve creation of polymorphic classes. Remember this when you learn about polymorphism next term.

• These mostly simplify conditional logic (if/then/else). Decompose Conditional is the most important. The parts of an if/then/else are replaced with method calls. These also clean up the use of flags to control sequencing or returns:

– if(o.foo()) o.bar() else o.baz();

• Switch statements can also be replaced with polymorphic classes.

• A null object is a real ‘do-nothing’ object that substitutes for a null value in a reference. It obviates the need to do an instanceOf test to check for null.

Page 26: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

5. Making Method Calls Simpler

• Rename Method• Add Parameter• Remove Parameter• Separate Query from

Modifier• Parameterize Method• Replace Parameter with

Explicit Methods• Preserve Whole Object• Replace Parameter with

Method

• Introduce Parameter Object

• Remove Setting Method• Hide Method• Replace Constructor

with Factory Method• Encapsulate Downcast• Replace Error Code with

Exception• Replace Exception with

Test

Page 27: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• These refactorings make interfaces easier to understand.

• Rename Method is convenient to document what a method does. Peter Dunne likes it a lot.

• Most of the remaining refactorings are used to get rid of parameters, but be cautious in concurrent programming. (Ask Chris Knowles why.)

• Factory methods hide the concrete implementation of an interface. Remember this when you learn about the Dependency Inversion Principle next term. This is the answer.

Page 28: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

6. Generalization

• Pull Up Field• Pull Up Method• Pull Up Constructor

Body• Push Down Method• Push Down Field• Extract Subclass

• Extract Superclass• Extract Interface• Collapse Hierarchy• Form Template

Method• Replace Inheritance

with Delegation• Replace Delegation

with Inheritance

Page 29: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments• I find it hard to get inheritance right from the

beginning.• These refactorings help clean up messy inheritance

hierarchies (like those in your projects).• They also allow you to evolve inheritance hierarchies

‘on the fly’, another common need.• Sometimes delegation works better than inheritance or

vice versa. Try both. (I will talk about ‘delegate, delegate, delegate’ again.)

Page 30: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

7. Big Refactorings• Tease Apart Inheritance

– Create two hierarchies from a complex one and use delegation to invoke one from the other.

• Convert Procedural Design to Objects– Turn data into objects; break up the behaviour; finally move

the behaviour into the objects.

• Separate Domain from Presentation– Move domain logic into separate domain classes.

• Extract Hierarchy– Subclass a very complex class with many special cases. (A

common need in student projects)

Page 31: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Comments

• Use “Tease Apart Inheritance” to simulate multiple inheritance.

• Use “Convert Procedural Design to Objects” to convert a procedural program to OO.

• Use “Separate Domain from Presentation” to fix a messy GUI.

• Use “Extract Hierarchy” to clean up complexity, particularly involving many special cases.

Page 32: What is Refactoring? CSE301 University of Sunderland Harry R. Erwin, PhD.

Conclusions

• Kent Beck says: This is “only the beginning.”• Why? Questions we’ve left unaddressed include

when to use refactoring and when to let well enough alone. That will be another lecture.

• Beck’s advice:– Pick an achievable goal– Stop when you’re unsure– Backtrack if necessary– Work with a partner

• I have some exercises involving refactoring.