Cpp Refactoring

Techniques for More Abstraction

Encapsulate Field

Field encapsulation [2] involves providing methods that can be used to read/write to/from the field rather than accessing the field directly. These methods are called accessor methods.

So instead of writing:

class A
{
public:
  int var;
};

You should write:

class A
{
public:
  int getVar();
  void setVar(int _var);
private:
  int var;
};

Type Generalization

Type generalization [3] is a technique for making more-generalized types.
Examples:

  • Moving a method from a child to a parent class.

Replace type-checking code with State/Strategy

Replace conditional with polymorphism

Composing Methods

Extract Method

Turn the fragment into a method whose name explains the purpose of the method.[4]

Example:

void printOwing(double amount) 
{
    printBanner();
 
    //print details
    cout << "name:" <<  name << endl;
    cout << "amount" << amount << endl;;
}

Can be refactored to:

void printOwing(double amount)
{
  printBanner();
  printDetails();
}
 
void printDetails()
{
   //print details
    cout << "name:" <<  name << endl;
    cout << "amount" << amount << endl;
}

Motivation

  • Other methods can use the new method
  • Higher-level methods are easier to understand.
  • Overriding is easier.

Inline Method

A method's body is just as clear as its name. [5]. When the body of a method is as clear as the name then you should get rid of the method.

Example:

int getRating()
{
  return (moreThanFiveLateDeliveries()) ? 2 : 1;
}
boolean moreThanFiveLateDeliveries()
{
  return numberOfLateDeliveries > 5;
}

Can be refactored to:

int getRating()
{
   return (_numberOfLateDeliveries > 5) ? 2 : 1;
}

Inline Temp

Temp variable that is assigned to once with a simple expression. [6]

Example:

double basePrice = anOrder.basePrice();
return (basePrice > 1000);

Can be refactored to:

return (anOrder.basePrice() > 1000);

Explaining Variables

Put the result of the expression in temporary variables with a name that explains the purpose. [7]

if ((platform.toUpperCase().indexOf("MAC") > -1) &&
   (browser.toUpperCase().indexOf("IE") > -1) &&
    wasInitialized() && resize > 0 ) {
         // do something
}

Can be refactored to:

final boolean isMacOs     = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE")  > -1;
final boolean wasResized  = resize > 0;
 
if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {
     // do something
}

Moving Features Between Objects

Extract Class

Techniques for improving names and location of code

Move Method / Move Field

Rename Method / Rename Field

Pull Up

Push Down

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.