定义
合成复用原则:尽量使用对象组合,而不是继承来达到复用的目的。
合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
组合复用可以使系统更加灵活,降低类与类之间的耦合度。
而使用继承,会大大增加类与类之间的耦合度,因为假如哪天被继承类的业务需要修改,或者被继承类的业务需要
另一个类来代替,那么继承类所继承的父类业务也需要去修改,这样做增大了工程量。并且继承子类还会继承父类
一些可能不想暴露的细节,这样并不安全。
代码实现
不使用合成复用原则
假设现在要出门,我们选择一双鞋穿出去。
定义一个Nike类。
/**
* @author John117
* @date 2022/05/24 12:24
*/
public class Nike {
//穿鞋方法
public void putOn() {
System.out.println("穿的是Nike鞋");
}
}
定义一个Foot类(其实这里用接口更符合规范,但是为了方便直接定义为类)。
/**
* @author John117
* @date 2022/05/24 12:29
*/
public class Foot extends Nike {
// 出门方法
public void goOut() {
putOn();
}
}
测试
/**
* @author John117
* @date 2022/05/24 12:29
*/
public class Test {
public static void main(String[] args) {
new Foot().putOn();
}
}
这么看其实没什么问题,但是假如现在要换一双鞋出门,那就必须改Foot类的继承,耦合太高了。
使用合成复用原则
定义Nike类和Adidas类
/**
* @author John117
* @date 2022/05/24 12:32
*/
public class Nike {
public void putOn() {
System.out.println("穿的是Nike鞋");
}
}
/**
* @author John117
* @date 2022/05/24 12:33
*/
public class Adidas {
public void putOn() {
System.out.println("穿的是Adidas鞋");
}
}
这时候就需要更改Foot类,不使用继承
方法一
可以这样写
/**
* @author John117
* @date 2022/05/24 12:33
*/
public class Foot {
Adidas adidas = new Adidas();
Nike nike = new Nike();
public void goOutByAdidas() {
adidas.putOn();
}
public void goOutByNike() {
nike.putOn();
}
}
然后测试
/**
* @author John117
* @date 2022/05/24 12:37
*/
public class Test {
public static void main(String[] args) {
new Foot().goOutByAdidas();
new Foot().goOutByNike();
}
}
方法二
也可以这样写
/**
* @author John117
* @date 2022/05/24 12:33
*/
public class Foot {
public void goOutByAdidas(Adidas adidas) {
adidas.putOn();
}
public void goOutByNike(Nike nike) {
nike.putOn();
}
}
测试
/**
* @author John117
* @date 2022/05/24 12:37
*/
public class Test {
public static void main(String[] args) {
new Foot().goOutByAdidas(new Adidas());
new Foot().goOutByNike(new Nike());
}
}
总结
合成复用原则其实就是,尽量使用聚合和组合的方式,进行解耦,降低耦合性,而不是使用继承
本文探讨了合成复用原则在软件设计中的优势,如何通过组合而非继承减少类间耦合,以Nike和Adidas为例,展示了如何通过对象组合实现灵活更换。同时,对比了不使用合成复用导致的高耦合问题和采用该原则后的解耦效果。
189





