Refactoring Extract Subclass
ProblemA class has features that are used only in certain cases.
SolutionCreate a subclass and use it in these cases.
Your main class has methods and fields for implementing a certain rare use case for the class. While the case is rare, the class is responsible for it and it would be wrong to move all the associated fields and methods to an entirely separate class. But they could be moved to a subclass, which is just what we will do with the help of this refactoring technique.
Creates a subclass quickly and easily.
You can create several separate subclasses if your main class is currently implementing more than one such special case.
Despite its seeming simplicity, Inheritance can lead to a dead end if you have to separate several different class hierarchies. If, for example, you had the class
Dogswith different behavior depending on the size and fur of dogs, you could tease out two hierarchies:
- by size:
- by fur:
And everything would seem well, except that problems will crop up as soon as you need to create a dog that is both
Smooth, since you can create an object from one class only. That said, you can avoid this problem by using Compose instead of Inherit (see the Strategy pattern). In other words, the
Dogclass will have two component fields, size and fur. You will plug in component objects from the necessary classes into these fields. So you can create a
- by size:
How to Refactor
Create a new subclass from the class of interest.
If you need additional data to create objects from a subclass, create a constructor and add the necessary parameters to it. Do not forget to call the constructor's parent implementation.
Find all calls to the constructor of the parent class. When the functionality of a subclass is necessary, replace the parent constructor with the subclass constructor.
Move the necessary methods and fields from the parent class to the subclass. Do this via Push Down Method and Push Down Field. It is simpler to start by moving the methods first. This way, the fields remain accessible throughout the whole process: from the parent class prior to the move, and from the subclass itself after the move is complete.
After the subclass is ready, find all the old fields that controlled the choice of functionality. Delete these fields by using polymorphism to replace all the operators in which the fields had been used. A simple example: in the Car class, you had the field
isElectricCarand, depending on it, in the
refuel()method the car is either fueled up with gas or charged with electricity. Post-refactoring, the
isElectricCarfield is removed and the
ElectricCarclasses will have their own implementations of the
Tired of reading?
No wonder, there are 7 hours worth of the text on this website.
Try out something different. We've just launched the interactive learning course on refactoring. It has more content and much more fun than a boring text.Learn more...
Everything is quite simple. This example is like video (but much cooler):
- After pressing the Play button, you will see floating messages, which will guide you through the example. You can proceed by clicking on them.
- You can fast-forward or return to previous steps by pressing arrow buttons on the left.
- Also, you can take a look at the code diff window, which will show what has changed in code during the example ()
- To check the code for errors, you can press "Compile and test" button ()