Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Refactor Like a Boss: Break the Classes

4.71/5 (8 votes)
18 Apr 2016CPOL1 min read 10.6K   31  
A tip for getting the most out of your refactoring practice

Action

Break the candidate class into multiple smaller classes.

Inspiration

Single Responsibility Principle from SOLID. Deals with God Class anti-pattern.

Identifying

To identify the candidates for this kind of refactoring, while reviewing a class you need to ask yourself what are the responsibilities of the class? If the answer is something like "What responsibilities? My class has only one responsibility, it does only this.", wonderful. But if the answer is "My class does this and that?", we have a problem. We need to separate "this" from "that" in two different class.

How

Let's consider that we have a AreaCalculator class and its responsibility is to calculate the area of the shape passed as argument. Pretty simple, huh? Okay, now for the sake of simplicity, let's say there are only two kinds of shapes:

  1. Squares
  2. Circles
C#
public class AreaCalculator
{
    private int sideOrRadius;
    private string shapeType;
 
    public AreaCalculator(int sideOrRadius, string shapeType)
    {
        this.sideOrRadius = sideOrRadius;
        this.shapeType = shapeType;
    }
 
    public double GetArea()
    {
        if (shapeType == "circle")
        {
            return 3.14 * sideOrRadius * sideOrRadius;
        }
        else if (shapeType == "square")
        {
            return sideOrRadius * sideOrRadius;
        }
 
        return 0;
    }
}

Now, ask yourself what your class is truly doing. It is calculating the area of the shapes. What are shapes? Squares and circles.

So, your class is calculating area of squares and calculating area of circles which is too many things to do for a class. We need to break functionality for circles and squares apart. Consider the classes below.

C#
public class Square
{
    private int side;
 
    public Square(int side)
    {
        this.side = side;
    }
 
    public int GetArea()
    {
        return side * side;
    }
}
 
public class Circle
{
    private int radius;
 
    public Circle(int radius)
    {
        this.radius = radius;
    }
 
    public double GetArea()
    {
        return 3.14 * radius * radius;
    }
}

Now, that we have two classes, their responsibilities are also divided in two parts. Now we don't have any God Class which needs to know the existence of every shapes existing on the face of the earth and how to calculate their area.

Opportunity

Breaking class practice opens up the opportunity to implement the Open-Close principle. Previously, if we need to add a new shape, we had to modify the existing AreaCalculator class. Now, we can just implement a new class without even touching the Square and Circle class.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)