Reconstruction Techniques: handling the generalization relation [3]. Reconstruction Techniques: generalization relations
Total returned directory
Directory of this section
- Extract BaseClass (Extract base class)
- Extract Interface (Extract Interface)
- Collapse Hierarchy (folding inheritance system)
7 Extract BaseClass (Extract base class) Overview
The two classes have similar features.Create a base class for these two classes and move the same featuresBase Class.
Motivation
Repeated Code is one of the worst in the system. If you do the same thing in different places, once you need to modify those actions, you have to make more changes in plain white.
Some form of repeated code is: two classes do similar things in the same way, Or do similar things in different ways. Objects provide a mechanism to simplify this situation, that is, inheritance. However, before creating these generic classes, you often cannot find such a common class. Therefore, after the common classes appear, you often start to establish the inheritance structure.
Example
The EatFood and Groom in the Dog class may be used by other classes because they are all public properties of animals, so we will consider refining them.
public class Dog{ public void EatFood() { // eat some food } public void Groom() { // perform grooming }}
The Code is as follows. The Animal method is extracted to encapsulate the public EatFood and Groom classes, so that other subclasses that inherit the Animal class can use these two methods.
public class Animal{ public void EatFood() { // eat some food } public void Groom() { // perform grooming }}public class Dog : Animal{}
Summary
This refactoring is a typical inheritance usage. Many programmers choose to do this, but pay attention to the correct use. Do not overuse inheritance. If it is overused, consider using interfaces, combinations, and aggregation.
This method is also frequently used, such as the BaseController In the MVC project.
8 Extract Interface (Extract Interface) Overview
Several customers use the same subset of the class interface, or the interfaces of the two classes are partially the same.Extracts the same subset into an independent interface.
Motivation
If a class plays different roles in different environments, it is a good idea to use interfaces. You can Extract the corresponding interfaces from the Extract Interface for each role. Another scenario where Extract Interface can be used is: You want to describe the external dependency interface of a class (outbound Interface, that is, the operation that this class requires the service provider to provide ). If you want to add other types of service objects in the future. You only need to require them to implement this interface.
Example
The TimeSheet class indicates the schedule for employees to work for the customer, from which the customer's payable fees can be calculated. To calculate these fees, TimeSheet needs to know the employee level and whether the employee has special skills:
class TimeSheet{ public double Charge(Employee emp, int days) { int baseCharge = emp.GetRate() * days; if (emp.HasSpecialSkill()) { return baseCharge * 1.05; } return baseCharge; }}class Employee{ public int GetRate() { return 2; } public bool HasSpecialSkill() { return true; }}
In addition to providing Employee level and special skill information, the Employee has many other features, but this application only needs these two features. You can define an interface for these two features to emphasize the fact that "I only need this feature:
public interface IBillable{ int GetRate(); bool HasSpecialSkill();}
Then, let the Employee implement this interface:
class Employee : IBillable{ public int GetRate() { return 2; } public bool HasSpecialSkill() { return true; }}
After that, modify the Charge () function declaration in the TimeSheet class and emphasize that this function only uses this part of the Employee behavior:
class TimeSheet{ public double Charge(IBillable emp, int days) { int baseCharge = emp.GetRate() * days; if (emp.HasSpecialSkill()) { return baseCharge * 1.05; } return baseCharge; }}
So far, we have gained a little bit in docalization. But for this function, such gains do not have much value. However, if several classes use the IBillable interface, it will be very useful. If I want to calculate the Computer rental fee, the huge gains will be revealed. to calculate the cost of the customer's Computer rental, we only need to make the Computer class implement the IBillable interface, then you can enter the time for renting a computer into the timetable.
Summary
This restructuring strategy is also a common application, and many design models will also use this idea.
9 Collapse Hierarchy (folding inheritance system) Overview
There is no big difference between a base class and a subclass.Integrate them into one.
Motivation
If you have written an inheritance system, you will know that the inheritance system is easily overly complicated. The so-called reconstruction of the inheritance system usually involves moving functions and fields up and down in the system. After completing these actions, you may find that a subclass does not bring this value. Therefore, you need to combine the base class and the subclass.
Example
As shown in the following code, the StudentWebSite subclass has no responsibility except for one attribute to indicate whether the website is active or not. In this case, we realize that the IsActive attribute can be applied to all websites, so we can move the IsActive attribute to the base class and remove the StudentWebSite class.
public class Website{ public string Title { get; set; } public string Description { get; set; } public IEnumerable<Webpage> Pages { get; set; }}public class StudentWebsite : Website{ public bool IsActive { get; set; }}public class Webpage{}
The code after reconstruction is as follows:
public class Website{ public string Title { get; set; } public string Description { get; set; } public IEnumerable<Webpage> Pages { get; set; } public bool IsActive { get; set; }}public class Webpage{}
Summary
This refactoring and the previous articles mainly discuss the inheritance relationships between child classes and parent classes and how to determine when to use inheritance. Generally, we can handle these relationships well, so it is relatively simple.
To Be Continued ......