合成复用原则(CRP)
非常好!你已经学习了好几个设计原则,现在我们来讲解合成复用原则(Composite Reuse Principle, CRP)——它和继承是常被比较的一对“重用方式”。
🧠 一句话定义
合成复用原则(CRP):尽量使用“组合/聚合”来实现代码复用,而不是通过继承。
🎯 为什么需要它?
在面向对象中,实现复用有两种方式:
方式 | 举例 | 特点 |
---|---|---|
✅ 组合(推荐) | 类 A 里包含类 B 的对象 | 灵活、低耦合 |
❌ 继承 | 类 A 继承类 B | 紧耦合、不灵活 |
我们常说:
继承是“白盒复用”(暴露了内部细节)
组合是“黑盒复用”(只暴露需要的接口)
✅ 优点 vs ❌ 缺点
✅ 优点 | ❌ 缺点 |
---|---|
更灵活:运行时可替换组件 | 初期代码稍多 |
低耦合:不受父类变动影响 | 多一层转发代码 |
可组合多个能力 | 不如继承简单直观 |
符合“面向接口编程”思想 | 不熟悉组合的人会嫌“啰嗦” |
🐍 Python 示例
❌ 继承复用(不推荐)
class Animal:def eat(self):print("Eating")class Dog(Animal):def bark(self):print("Barking")d = Dog()
d.eat() # ✅ 复用到了
d.bark()
但如果 Animal
改了,你就可能连 Dog
都出 bug —— 继承让两个类“绑死”了。
✅ 合成复用(推荐)
class AnimalBehavior:def eat(self):print("Eating")class Dog:def __init__(self):self.behavior = AnimalBehavior() # 组合进来def bark(self):print("Barking")def eat(self):self.behavior.eat() # ✅ 委托给组合对象
Dog
拥有AnimalBehavior
的能力;- 如果将来
AnimalBehavior
换成VeganAnimalBehavior
,不用改Dog
结构; - 更灵活、更安全!
🧭 结构图(Mermaid)
📦 典型应用场景
- 游戏角色拥有多个“能力”(组合而非继承)
- 构建服务时组合多个服务(AuthService, LoggingService)
- GUI 系统中组件组合成更复杂的 UI(而不是继承出所有种类)
🏁 总结口诀
🧩 能用组合,就别继承!继承是一种“硬绑定”,组合才是“灵活拼装”。
🔁 总结对比:组合 vs 继承
比较项 | 继承 | 组合 |
---|---|---|
耦合度 | 高(父变子崩) | 低(组合可替) |
灵活性 | 固定继承体系 | 可组合多个能力 |
可替代性 | 差 | 强(运行时替换) |
设计模式支撑 | Template Method | Strategy, Decorator 等 |
如果你希望我用一个真实项目例子(比如:支付系统、角色技能系统、Web Controller组合)来演示「组合复用」的效果,我可以继续带你写一段小实战!
要不要试试看?🚀