Sie sind auf Seite 1von 51

REFACTORING

Submitted By
ANIL ARORA
(10/05)
What it Refactoring?
 Refactoring is a disciplined process of
changing a software system in such a
way that it does not alter the external
behavior of the code while at the same
time improves its internal structure.
 This is sometimes called “Improving the
design after it has been written”
 INCREMENTAL DESIGN!
(Very) Simple Example
Consolidate Duplicate Conditional Fragments

This becomes this

if (isSpecialDeal()) if (isSpecialDeal())
{
{
total = price * 0.95;
send() total = price * 0.95;
} }
else else
{ {
total = price * 0.98;
total = price * 0.98;
send()
} }
send();
Principles
 The purpose of refactoring is to make software
easier to understand and modify
 Contrast this with performance optimization
 Again functionality is not changed, only internal
structure; however performance optimizations
often involve making code harder to understand
(but faster!)
Why should you refactor?
 Refactoring improves the design of software
 without refactoring, a design will “decay” as people make
changes to a software system
 Refactoring makes software easier to understand
 because structure is improved, duplicated code is eliminated,
etc.
 Refactoring helps you find bugs
 Refactoring promotes a deep understanding of the code at hand,
and this understanding aids the programmer in finding bugs and
anticipating potential bugs
 Refactoring helps you program faster
 because a good design enables progress
Why should refactoring be done?

 Refactoring Improves the Design of


Software
 Refactoring Makes Software Easier to
Understand
 Refactoring Helps You Find Bugs
 Refactoring Helps You Program Faster
When Should You Refactor?
 Refactor When You Add Function
 do it before you add the new function to
make it easier to add the function
 or do it after to clean up the code after the
function is added
 Refactor When You Need to Fix a Bug
 Refactor As You Do a Code Review
 When you encounter a “bad smell”…
Bad Smells in Code
 Duplicated Code
 badbecause if you modify one instance of
duplicated code but not the others, you (may)
have introduced a bug!
 Long Method
 longmethods are more difficult to understand;
performance concerns with respect to lots of
short methods are largely obsolete
Bad Smells in Code
 Large Class
 Large classes try to do too much, which reduces
cohesion
 Long Parameter List
 hard to understand, can become inconsistent
 Divergent Change
 Deals with cohesion; symptom: one type of change
requires changing one subset of methods; another
type of change requires changing another subset
Bad Smells in Code
 Shotgun Surgery
a change requires lots of little changes in a lot of
different classes
 Feature Envy
A method requires lots of information from some other
class (move it closer!)
 Data Clumps
 attributes
that clump together but are not part of the
same class
Bad Smells in Code
 Primitive Obsession
 characterized by a reluctance to use classes instead
of primitive data types
 Switch Statements
 Switch statements are often duplicated in code; they
can typically be replaced by use of polymorphism (let
OO do your selection for you!)
 Parallel Inheritance Hierarchies
 Similar to Shotgun Surgery; each time I add a
subclass to one hierarchy, I need to do it for all
related hierarchies
Bad Smells in Code
 Lazy Class
 A class that no longer “pays its way” e.g. may be a class that
was downsized by refactoring, or represented planned
functionality that did not pan out
 Speculative Generality
 “Oh I think we need the ability to do this kind of thing someday”
 Temporary Field
 An attribute of an object is only set in certain circumstances; but
an object should need all of its attributes
Bad Smells in Code
 Message Chains
 a client asks an object for another object and then asks that
object for another object etc. Bad because client depends on the
structure of the navigation
 Middle Man
 If a class is delegating more than half of its responsibilities to
another class, do you really need it?
 Inappropriate Intimacy
 Pairs of classes that know too much about each other’s private
details
Refactoring Methods
 Add Parameter  Extract Interface
 Change Association  Extract method
 Reference to value  Extract subclass
 Value to reference  Extract superclass
 Collapse hierarchy  Form template method
 Consolidate  Hide delegate
conditionals  Hide method
 Procedures to objects  Inline class
 Decompose conditional  Inline temp
 Encapsulate collection  Introduce assertion
 Encapsulate downcast  Introduce explain variable
 Encapsulate field  Introduce foreign method
 Extract class
Refactoring Methods Contd.
Extract Method
 You have a code fragment that can be
grouped together
 Turn the fragment into a method whose
name explains the purpose of the
fragment
Extract Method Example
void printOwing(double amount)
{
printBanner()
BEFORE
//print details
Console.Writeline(“name: ” + _name);
Console.Writeline(“amount: ” + amount);
}

void printOwing(double amount)


{
printBanner() AFTER
printDetails(amount)
}

void printDetails(double amount)


{
Console.Writeline(“name: ” + _name);
Console.Writeline(“amount: ” + amount);
}
What are some refactoring
examples?
 Move Field - Motivation is to move
responsibilities from one class to another.
 Extract Class - Motivation: A class with
many methods and lots of data needs to
be split
Push Down Method

 Behavior on a superclass is relevant only


for some of its subclasses.
 Move the behavior to the subclass
Pull Up Method
Extract Class
Extract Subclass
public class Person public class Person
{ {
private string name; protected string name;
private string jobTitle; }
} public class Employee :Person
{
private string jobTitle;
}
Extract SuperClass
public class Employee public class Student
{ {
private string name; private string name;
private string private Course course;
jobTitle; }
}
Contd...
public abstract class Person
{
protected string name;
}
public class Employee : Person
{
private string jobTitle;
}
public class Student : Person
{
private Course course;
}
Move Field
1. Create a field in the target class with getter and
setter methods.
2. Compile and test.
3. Determine how to reference the target object from
the source.
4. Remove the field on the source class.
5. Replace all references to the source field with the
reference to the appropriate method on the target.
6. Compile and test.
// Move Field Example Account Class Before
package refactoringlecture.moveFieldBefore;

public class Account {

private AccountType _type;


private double _interestRate;

double interestForAmount_days(double amount, int days) {


return _interestRate * amount * days /365;
}

public Account() {
}
}
//Move Field Example AccountType Class Before
package refactoringlecture.moveFieldBefore;

public class AccountType {

public AccountType() {
}
}
//Move Field Example Account Class After
package refactoringlecture.moveFieldAfter;
public class Account {

private AccountType _type;

double interestForAmount_days(double amount, int days) {


return _type.getInterestRate() * amount * days /365;
}

public Account() {
}
}
//Move Field AccountType After
package refactoringlecture.moveFieldAfter;

public class AccountType {

private double _interestRate;

void setInterestRate (double arg) {


_interestRate = arg;
}

double getInterestRate(){
return _interestRate;
}

public AccountType() {
}
}
Extract Class
1. Decide how to split the responsibilities.
2. Create a new class to express the split-off
responsibilities
3. Make a link from the old to the new class
4. Use Move Field on fields to be moved
5. Compile and Test
6. Use Move Method on Method to be moved
7. Compile and Test
8. Review and reduce the interface of each class
9. Decide whether to expose the new class.
// Extract Class Example Person Class Before public String getOfficeAreaCode(){
package refactoringlecture.extractClassBefore; return _officeAreaCode;
public class Person {
}
private String _name;
public void setOfficeAreaCode(String arg){
private String _officeAreaCode;
_officeAreaCode=arg;
private String _officeNumber;
}

public Person() { public String getOfficeNumber() {


} return _officeNumber;
}
public String getName() { public void setOfficeNumber(String arg) {
return _name;
_officeNumber=arg;
}
}
public String getTelephoneNumber() {
}
return ("(" + _officeAreaCode + ") " +
_officeNumber);
}
//Extract Class Example public String getTelephoneNumber() {

//Person Class After return


_officeTelephone.getTelephoneNumber();
package
}
refactoringlecture.extractClassAfter;

TelephoneNumber getOfficeTelephone(){
public class Person {
return _officeTelephone;
}
private String _name;
private TelephoneNumber public Person() {
_officeTelephone }
= new TelephoneNumber(); }

public String getName() {


return _name;
}
//Extract Class Example public void setAreaCode(String arg) {
//TelephoneNumber Class After _areaCode=arg;
package }
refactoringlecture.extractClassAfter;
public String getNumber() {
public class TelephoneNumber {
return _number;
private String _areaCode;
}
private String _number;
public void setNumber(String arg) {
_number=arg;
public String getTelephoneNumber() {
}
return ("(" + _areaCode + ") " +
public TelephoneNumber() {
_number);
}
}
}

public String getAreaCode() {


return _areaCode;
}
Bad Smells in Code
Duplicated Code.
Long Method.
Parallel Inheritance Hierarchies.
Lazy Class.
Speculative Generality.
Temporary Field.
Message Chains.
Middle Man.
Inappropriate Intimacy.
Alternative Classes with Different
Interfaces.
Incomplete Library Class.
Data Class.
Refused Bequest.
Comments.
Large Class.
Long Parameter List.
Divergent Change.
Shotgun Surgery.
Push Down Method
Behavior on a superclass is
relevant only for
some of its subclasses.
Defining Refactoring
 (Noun) – A change made to internal
structure of software to make it easier to
understand and modify without changing
its observable behavior.
 (Verb) – to structure software by applying
a series of refactorings without changing
its observable behavior
Database Refactoring
 A database refactoring is a small change
to a database schema which improves its
design without changing, at a practical
level, the semantics of the database. In
other words, it is a simple database
transformation which neither adds nor
breaks anything.
Why Database Refactoring?

 To repair existing legacy databases.


 To support evolutionary software
development
Types Of Database Refactoring
 Structural. A change to the table structure of your database
schema.
 Data quality. A change which improves and/or ensures the
consistency and usage of the values stored within the database.
 Referential integrity. A change which ensures that a referenced
row exists within another table and/or that ensures that a row which
is no longer needed is removed appropriately.
 Architectural. A change which improves the overall manner in
which external programs interact with a database.
 Method. A change which improves the quality of a stored
procedure, stored function, or trigger.
 Non-refactoring transformations. A change which changes the
semantics of your database schema by adding new elements to it or
by modifying existing elements.
Database Refactoring

 A database refactoring is a simple change to a database


schema that improves its design while retaining both its
behavioral and informational semantics.
 A database schema includes both structural aspects
such as table and view definitions as well as functional
aspects such as stored procedures and triggers.
 Important: Database refactorings are a subset of
schema transformations, but they do not add
functionality.
Why DB Refactoring is Hard
Rename Column
Replace Column
Merge Columns

Das könnte Ihnen auch gefallen