版权声明

  • 本文原创作者:谷哥的小弟
  • 作者博客地址:http://blog.csdn.net/lfdfhl

参考资料

  1. 《大话设计模式》 作者:程杰
  2. 《Java设计模式》 作者:刘伟
  3. 《图解设计模式》 作者:结城浩
  4. 《重学Java设计模式》 作者:付政委
  5. 《Head First设计模式》作者:埃里克·弗里曼

合成复用原则概述

合成复用原则又称为组合/聚合复用原则,即Composition/Aggregate Reuse Principle,CARP。

该原则定义如下:

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

Favor composition of objects over inheritance as a reuse mechanism

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

在面向对象设计中可以通过两种方法在不同的环境中复用已有的设计和实现,即通过组合/聚合关系或通过继承。但首先应该考虑使用组合/聚合,组合/聚合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少;其次才考虑继承。在使用继承时需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。

通过继承来进行复用的主要问题在于继承复用会破坏系统的封装性,因为继承会将基类的实现细节暴露给子类,由于基类的某些内部细节对子类来说是可见的,所以这种复用又称“白箱”复用,如果基类发生改变,那么子类的实现也不得不发生改变。

由于组合或聚合关系可以将已有的对象(也可称为成员对象)纳入到新对象中,使之成为新对象的一部分。因此新对象可以调用已有对象的功能,这样做可以使成员对象的内部实现细节对于新对象不可见,所以这种复用又称为“黑箱”复用,相对继承关系而言,其耦合度相对较低,成员对象的变化对新对象的影响不大,可以在新对象中根据实际需要有选择性地调用成员对象的操作。

一般而言,如果两个类之间是“Has-A”的关系应使用组合或聚合,如果是“Is-A”的关系可以使用继承。“Is-A”是严格的分类学意义上的定义,意思是一个类是另一个类的“一种”;而“Has-A”则不同,它表示某一个角色具有某一项责任。

合成复用原则案例1

在此,以案例形式介绍合成复用原则。

版本1

在项目技术选型中采用MySQL数据库存储数据,并利用MySQL数据库连接对用户进行添加操作。

DBConnection

package com.carp01;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class DBConnection {public String getConnection() {return "获取MySQL数据库连接";}
}

UserDao

package com.carp01;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class UserDao extends DBConnection {public void addUser() {String connection = super.getConnection();System.out.println(connection);System.out.println("执行数据库操作");// ......省略后续操作......}
}

Test

package com.carp01;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class Test {public static void main(String[] args) {UserDao userDao = new UserDao();userDao.addUser();}
}

小结

在该示例中UserDao继承自DBConnection,getConnection( )方法只能返回MySQL数据库的连接。但是,随着业务的扩展功能增加了;又新增了Oracle数据库。此时,原本的UserDao就不能满足需求了。虽然,我们可在DBConnection中再新增一个方法用于获取 Oracle 数据库的连接;但是这样显然违反了开闭原则。

版本2

我们利用合成复用原则对示例代码进行重构。将数据库连接类设计为抽象类,其内部包含一个获取数据库连接的抽象方法;至于获取哪种数据库的连接则交于具体的子类去实现。另外,我们在UserDao中持有DBConnection类型的引用。

DBConnection

package com.carp02;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public abstract class DBConnection {public abstract String getConnection();
}

MySQLConnection

package com.carp02;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class MySQLConnection extends DBConnection {@Overridepublic String getConnection() {return "获取MySQL数据库连接";}
}

OracleConnection

package com.carp02;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class OracleConnection extends DBConnection {@Overridepublic String getConnection() {return "获取Oracle数据库连接";}
}

UserDao

package com.carp02;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class UserDao {// 持有DBConnection类型的引用private DBConnection connection;public void setConnection(DBConnection connection) {this.connection = connection;}public void addUser() {System.out.println(connection);System.out.println("执行数据库操作");// ......省略后续操作......}
}

Test

package com.carp02;
/*** 原创作者:谷哥的小弟* 博客地址:http://blog.csdn.net/lfdfhl*/
public class Test {public static void main(String[] args) {UserDao userDao = new UserDao();MySQLConnection mySQLConnection = new MySQLConnection();userDao.setConnection(mySQLConnection);userDao.addUser();OracleConnection oracleConnection = new OracleConnection();userDao.setConnection(oracleConnection);userDao.addUser();}
}

合成复用原则案例2

汽车按“动力源”划分可分为汽油汽车、电动汽车等;按“颜色”划分可分为白色汽车、黑色汽车和红色汽车等。如果同时考虑这两种分类,其组合就很多;图示如下:

从上面类图我们可以看到:使用继承复用产生了很多子类,如果现在又有新的动力源或者新的颜色的话,就需要再定义新的类。在此,我们试着将继承复用改为聚合复用;图示如下:

面向对象编程原则(08)——合成复用原则相关推荐

  1. 软件设计原则之接口隔离原则、合成复用原则、迪米特原则

    系列文章目录 软件设计原则之单一职责原则.开闭原则 软件设计原则之里氏替换原则.依赖倒置原则 软件设计原则之接口隔离原则.合成复用原则.迪米特原则 文章目录 系列文章目录 一.接口隔离原则 什么是接口 ...

  2. 七大设计原则之合成复用原则

    一.合成复用原则介绍 合成复用原则是指尽量使用合成/聚合的方式,而不是使用继承.类图介绍如下: 二.依赖关系.组合关系.聚合关系介绍 2.1依赖关系(Dependency) 只要是在类中用到了对方,那 ...

  3. 面向对象设计原则之合成复用原则

    合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下: 合成复用原则(Composite Reuse Princi ...

  4. Java设计模式之设计的6大原则(开闭原则,里氏代换原则,依赖倒转原则,接口隔离原则,最少知道原则,合成复用原则)

    1. 开闭原则 核心思想:一个对象对外扩展开发,对修改关闭 意思就是:对类的改动是通过增加代码进行的,而不是修改现有的代码. 也就是说软件开发人员一旦写出了可以运行的代码,就不应该去改动它,而是要保证 ...

  5. 设计原则之合成复用原则

    合成复用原则是指: 尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现. 通常类的复用分为继承复用和合成复用两种. 继承复用虽然有简单和易实现的优点,但它也存在以下缺点: 1. 继承 ...

  6. 软件设计原则 —— 迪米特原则和合成复用原则

    迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的 ...

  7. 设计原则-迪米特原则与合成复用原则

    迪米特原则(Law of Demeter LoD) 迪米特原则又叫最少知道原则(Least Knowledge Principle,LKP),这里的最少知道主要是强调,调用者对传入的参数,和接受到的返 ...

  8. 设计模式-合成复用原则-》面向对象设计原则

    合成复用原则是面向对象设计原则的 7 条原则中剩下的最后一条,下面我们将对其进行详细地介绍. 合成复用原则的定义 合成复用原则(Composite Reuse Principle,CRP)又叫组合/聚 ...

  9. 融会贯通——最常用的面向对象设计原则“合成复用原则”

    复用一个类的时候,多使用对象的组合/聚合的关联关系,而不是继承. 之前提到的"依赖倒转原则",是以里氏代换原则为基础的实现开闭原则目标的手段,这一条路线涉及到的是类的继承(包括单继 ...

最新文章

  1. 可复现的图像降噪算法总结——超赞整理
  2. Android Studio教程10-Intent的详细使用
  3. win7 64位 安装java jdk1.8 ,修改配置环境变量
  4. [Luogu] P4198 楼房重建
  5. 计网 - 传输层协议 TCP:TCP 为什么握手是 3 次、挥手是 4 次?
  6. UITextView
  7. 零基础学python难吗-零基础入门学习Python技术难不难?
  8. 为什么网站服务器不存在了,百度数据中有网站不存在的路径是什么原因
  9. 3. mysql的注解驱动的三种方式_注册 Jdbc 驱动程序的三种方式及Class.forName 的作用...
  10. 3 docker容器
  11. 【分享】迅为iTOP4412开发板-Android系统屏幕旋转设置
  12. java物流专线快运系统源码TMS
  13. 嵌入式系统开发环境的构建08:在Hyper-V中安装Windows XP操作系统
  14. 号外,号外,《React Native移动开发实战》出版啦
  15. CTF练习题——bugkuCTF 网站被黑题目思路分析
  16. QT: 为自己的QT程序添加一个登录界面
  17. 国内云服务地域选择和测速
  18. 怎么给表格加一列序号_(表格的序号怎么顺下来)如何在excel表格填充一列序号列...
  19. 侍魂qq最新服务器,qq区怎么进不去了,说服务器未开启
  20. 【基于SSH框架的个人博客系统05】ajax异步通讯技术与json交互

热门文章

  1. android 英语
  2. type-c方案 USB-C方案芯片方案 苹果type-c芯片方案 type-c PD芯片方案
  3. android签名原理
  4. SAP 理解合并会计报表
  5. (附源码)SSM校园闲置物品交易系统JAVA计算机毕业设计项目
  6. linux的diff工具原理之Myers算法
  7. 《PHP程序员面试笔试宝典》——如何准备集体面试?
  8. 连接oracle数据库报错:ORA-12505
  9. 知识付费找副业的平台哪个好?业内人士这么说
  10. 知道被测物的长、宽、高以及要求的测量精度,如何来选择 CCD 相机和工业镜头,选择以上器件需要注意什么?