深入理解合成复用原则(Composition /Aggregate Reuse Principle)

简介: 深入理解合成复用原则(Composition /Aggregate Reuse Principle)

合成复用原则

合成复用原则(Composition /Aggregate Reuse Principle)

合成复用原则又称为组合/聚合复用原则。

优先使用对象组合,而不是通过继承来达到复用的目的。

What:什么是合成复用原则

在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用已有的对象,使之成为新对象的一部分。新对象通过调用已有对象的方法达到复用功能的目的。简而言之,在复用时要尽量使用组合/聚合关系(关联关系),少用继承。

Why:为什么要使用合成复用原则

在面向对象设计中主要有两种方式复用已有的设计和实现,第一种是通过合成复用原则,另外一种是通过继承。但是应该首先考虑使用组合/聚合。使用组合/聚合原则可以使系统更加灵活,降低类与类之间的耦合性,一个类的变化对其他类造成的影响相对较少。

1、由于组合聚合关系可以将已有的对象纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能。这样做可以使成员对象的内部实现细节对于新对象不可见。


2、相对于继承关系而言,耦合度较低,成员对象的变化对新对象的影响不大,可以在新对象中根据实际需要有选择性地调用成员对象的操作。


3、合成复用原则可以在运行时动态进行,新对象可以动态的引用于成员对象类型相同的其他对象。

通过继承来进行复用的主要问题:

1、继承复用会破坏系统的封装性,因为继承会将基类的实现细节暴露给子类,基类的某些内部细节对于子类来说是可见的。如果基类发生改变,子类的实现也不得不发生改变。
2、从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性。

3、而且继承只能在有限的环境中使用。

How:怎么使用组合/聚合原则

一般来说,如果两个类之间是Has-A的关系应该使用组合/聚合,如果是Is-A关系可以使用继承。

示例

某公司开发人员在初期的CRM系统设计中考虑到客户数量不多采用Access作为数据库,与数据库操作有关的类如CustomerDAO类等都需要连接数据库,连接数据库的方法getConnection()封装在DBUtil类中,由于需要重用DButil类的getConnection()方法,设计人员将CustomerDAO作为DBUtil类的子类,如图:


随着客户数量的增多,系统决定升级为Oracle数据库,因此需要正价一个新的OracleDBUtil类来连接Oracle数据库,由于在初始设计方案中CustomerDAO和DButil之间是继承关系,因此在更换数据库连接方式时需要修改CutomerDAO类的源代码,将CustomerDAO作为OracleDBUtil的子类这将违背开闭原则,也可以直接修改DBUtil的源代码,但是也违背了开闭原则。


现在使用组合/聚合原则进行重构。


根据合成复用原则,在实现复用时应该多用关联,少用继承。在本实例中可以使用关联复用来取代继承复用,重构后的结构。



在图中,CustomerDAO和DBUtil之间的关系由继承关系变成关联关系,采用依赖注入的方式将DBUtil对象注入到CustomerDAO中,也可以使用构造注入,也可以使用设值注入。如果需要对DBUtil的功能进行扩展,可以通过其子类来实现,例如通过自来OracleDBUtil来连接Oracle数据库。由于CustomerDAO针对DBUtil编程,根据里氏替换原则,DBUtil子类的对象可以覆盖DButil对象,只需要在CustomerDAO中注入子类对象,就可以使用子类所扩展的方法。例如在CustomerDAO中注入OracleDBUtil对象,及可实现Oracle数据库连接,原有代码无需进行修改,而且可以很灵活的增加新的数据库连接方式,符合开闭原则。

后记

对于设计模式七大原则的学习,小编的博客只是对小编自己阶段学习的一个总结,其中有不合理的地方环境大家指出一起交流,并且小编学习的内容主要源自于书籍。

参考数据《Java设计模式》、《图解设计模式》。

目录
相关文章
|
6月前
|
Java
六大设计原则-里式替换原则【Liskov Substitution Principle】
六大设计原则-里式替换原则【Liskov Substitution Principle】
22 0
|
6月前
六大设计原则-单一职责原则【Single Responsibility Principle】
六大设计原则-单一职责原则【Single Responsibility Principle】
26 0
|
图形学 异构计算
Unity【LOD Group】- 关于性能优化中LOD的使用与总结
Unity【LOD Group】- 关于性能优化中LOD的使用与总结
599 0
Unity【LOD Group】- 关于性能优化中LOD的使用与总结
|
程序员
单一职责原则(Single Responsibility Principle,SRP)(上)
单一职责原则(Single Responsibility Principle,SRP)
118 0
单一职责原则(Single Responsibility Principle,SRP)(上)
|
数据安全/隐私保护 iOS开发
单一职责原则(Single Responsibility Principle,SRP)(中)
单一职责原则(Single Responsibility Principle,SRP)(中)
192 0
单一职责原则(Single Responsibility Principle,SRP)(中)
|
设计模式 项目管理 数据库
单一职责原则(Single Responsibility Principle,SRP)(下)
单一职责原则(Single Responsibility Principle,SRP)(下)
395 0
单一职责原则(Single Responsibility Principle,SRP)(下)
【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)
【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)
|
测试技术
【愚公系列】2021年12月 面向对象设计原则(一)-单一职责原则(Single Responsibility Principle or SRP)
【愚公系列】2021年12月 面向对象设计原则(一)-单一职责原则(Single Responsibility Principle or SRP)
127 0
|
设计模式 C#
【愚公系列】2021年12月 通用职责分配原则(四)-高内聚原则(High Cohesion Principle)
【愚公系列】2021年12月 通用职责分配原则(四)-高内聚原则(High Cohesion Principle)
|
设计模式 C#
【愚公系列】2021年12月 通用职责分配原则(三)-低耦合原则(Low Coupling Principle)
【愚公系列】2021年12月 通用职责分配原则(三)-低耦合原则(Low Coupling Principle)
102 0