第十一章系统介绍了一系列处理概括关系的重构手法,旨在优化继承关系和其他类型的概括关系,提高代码的可维护性和可读性。这是这一章中列举的一些处理概括关系的重构手法:
问题:有些子类共享相同的特性。
解决方法:把这些特性抽取到一个共同的地方,让所有子类都能使用。
bash
// 之前
class 矩形 {
宽度;
}
class 正方形 extends 矩形 {
// 正方形独有的属性
}
// 之后
class 形状 {
宽度;
}
class 矩形 extends 形状 {
// 矩形独有的属性
}
class 正方形 extends 形状 {
// 正方形独有的属性
}
问题:有些子类有相同的行为。
解决方法:将这些相同的行为提取到更高一级,让所有子类都能用。
// 之前
class 鸟 {
飞() {
// 飞翔逻辑
}
}
class 麻雀 extends 鸟 {
// 麻雀特有的方法
}
// 之后
class 鸟 {
飞() {
// 飞翔逻辑
}
}
class 麻雀 extends 鸟 {
// 麻雀特有的方法
}
问题:不同子类的构造方法有相似的步骤。
解决方法:把这些相似的构造方法逻辑移到父类中,让所有子类都能调用。
// 之前
class 车辆 {
车辆(int 燃油) {
// 公共的构造逻辑
}
}
class 汽车 extends 车辆 {
汽车(int 燃油, int 乘客) {
super(燃油);
// 汽车特有的构造逻辑
}
}
// 之后
class 车辆 {
车辆(int 燃油) {
// 公共的构造逻辑
}
}
class 汽车 extends 车辆 {
汽车(int 燃油, int 乘客) {
super(燃油);
// 汽车特有的构造逻辑
}
}
问题:父类中的方法只有某个子类使用。
解决方法:将只有某个子类使用的方法移到该子类中,使得方法更加局部化。
// 之前
class 动物 {
游泳() {
// 游泳逻辑
}
}
class 鱼 extends 动物 {
// 鱼的独有方法
}
// 之后
class 动物 {
// 动物的独有方法
}
class 鱼 extends 动物 {
游泳() {
// 游泳逻辑
}
}
问题:父类中的字段只有某个子类使用。
解决方法:将只有某个子类使用的字段移到该子类中,使得字段更加局部化。
// 之前
class 员工 {
姓名;
}
class 经理 extends 员工 {
// 经理的独有属性
}
// 之后
class 员工 {
// 员工的独有属性
}
class 经理 extends 员工 {
姓名;
// 经理的独有属性
}
问题:有些类具有相似的方法。
解决方法:将相似的方法提取成一个接口,让多个类都能实现这个接口。
// 之前
class 狗 {
叫() {
// 叫的逻辑
}
}
class 猫 {
// 猫的独有方法
}
// 之后
接口 动物 {
void 发出声音();
}
class 狗 implements 动物 {
void 发出声音() {
// 叫的逻辑
}
}
class 猫 implements 动物 {
// 猫的独有方法
}
问题:很多类有相似的属性和方法。
解决方法:将相似的属性和方法提取到一个超类中,让多个类都能继承这个超类。
// 之前
class 圆形 {
直径;
计算面积() {
// 计算逻辑
}
}
class 长方形 {
宽度;
计算面积() {
// 计算逻辑
}
// 长方形的独有方法
}
// 之后
class 形状 {
尺寸;
计算面积() {
// 计算逻辑
}
}
class 圆形 extends 形状 {
// 圆形独有的方法
}
class 长方形 extends 形状 {
// 长方形独有的方法
}
问题:子类的逻辑只是调用了父类的方法,没有实际的扩展。
解决方法:用委托关系替代继承关系,让子类成为父类的助手。
// 之前
class 打印机 {
打印() {
// 打印逻辑
}
}
class 彩色打印机 extends 打印机 {
// 彩色打印机独有的方法
}
// 之后
class 打印机 {
打印() {
// 打印逻辑
}
}
class 彩色打印机助手 {
private 打印机 打印机;
彩色打印() {
// 彩色打印逻辑
打印机.打印();
}
}
问题:继承体系中的层次关系显得过于繁琐。
解决方法:简化层次结构,减少不必要的层次。
// 之前
class 哺乳动物 {
// 哺乳动物的方法
}
class 狗 extends 哺乳动物 {
// 狗的独有方法
}
// 之后
class 狗 {
// 狗的独有方法
}
问题:使用类型码表示不同的类型,而这些类型可以通过子类表示。
解决方法:将类型码替换为子类,每个子类代表一个具体的类型。
// 之前
class 动物 {
类型; // 1 代表狗, 2 代表猫, 等等
发出声音() {
// 发声逻辑
}
}
// 之后
abstract class 动物 {
abstract void 发出声音();
}
class 狗 extends 动物 {
void 发出声音() {
// 狗的声音逻辑
}
}
class 猫 extends 动物 {
void 发出声音() {
// 猫的声音逻辑
}
这些建议有助于优化类之间的关系,提高代码的可读性和可维护性。在使用这些技巧时,要根据实际情况选择最适合你的方法,确保代码清晰易懂,确保代码的质量和可维护性。