一、设计模式合成复用原则定义
在软件程序复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。
如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
二 、原则作用
通常类的复用分为继承复用和合成复用两种,继承复用虽然有简单和易实现的优点,但它也存在以下缺点。
- 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
- 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。
- 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。
采用组合或聚合复用时,可以将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,它有以下优点。
- 它维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
- 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口。
- 复用的灵活性高。这种复用可以在运行时动
三、原则实现实例
合成复用原则是通过将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而达到复用。
1、新建main.java空白文件,cursor输入指令
2、自动生成代码以及文件
2.1、Main.java代码如下:
public class Main {
public static void main(String[] args) {
Engine petrolEngine = new Engine("Petrol");
Engine electricEngine = new Engine("Electric");
Transmission manualTransmission = new Transmission("Manual");
Transmission automaticTransmission = new Transmission("Automatic");
Car petrolCar = new Car("Sedan", petrolEngine, manualTransmission);
Car electricCar = new Car("Tesla", electricEngine, automaticTransmission);
System.out.println("--- Starting Petrol Car ---");
petrolCar.start();
System.out.println("\n--- Starting Electric Car ---");
electricCar.start();
}
}
这个例子展示了合成复用原则的应用:
- 我们创建了独立的 Engine 和 Transmission 类,而不是通过继承来创建不同类型的汽车。
- Car 类通过组合使用 Engine 和 Transmission,而不是继承它们。
这种方式允许我们灵活地组合不同类型的引擎和变速器,而不需要为每种组合创建一个新的子类。
2.2、Engine.java代码如下:
public class Engine {
private String type;
public Engine(String type) {
this.type = type;
}
public void start() {
System.out.println(type + " engine starting...");
}
}
2.3、Transmission.java代码如下:
public class Transmission {
private String type;
public Transmission(String type) {
this.type = type;
}
public void shift() {
System.out.println("Shifting gears with " + type + " transmission");
}
}
3、运行主程序输出
这个输出直观地展示了不同类型的汽车如何使用不同的引擎和变速器组件。通过使用组合而不是继承,我们可以:
更灵活地创建不同类型的汽车,而不需要复杂的继承层次。
轻松地添加新的引擎或变速器类型,而不影响现有的代码。
避免因继承带来的紧耦合,使系统更容易维护和扩展。
这个例子展示了合成复用原则如何帮助我们创建更灵活、可维护的代码结构,同时仍然实现了代码的重用。