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

技术面向对象设计原则之合成复用原则 面向对象设计原则之合成复用原则转载来自:https://blog.csdn.net/lovelion/article/details/7563441
合成复用原则又称

面向对象设计原则的组成和重用原则。

转载自:https://blog.csdn.net/lovelion/article/details/7563441

组合原则,也称为组合/聚合重用原则(carp),定义如下:

合成复用原则(Composite Reuse Principle, CRP):尽量使用对象组合,而不是继承来达到复用的目的。

组合的原理是通过关联关系(包括组合关系和聚合关系)将一个新对象中已有的一些对象利用起来,使它们成为新对象的一部分。新对象通过委托现有对象的方法来达到重用功能的目的。简而言之,应该尽可能使用组合/聚合关系(关联关系),少用继承。

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

通过继承进行重用的主要问题是继承重用会破坏系统的封装,因为继承会将基类的实现细节暴露给子类。由于基类的内部细节通常对子类可见,这种重用也被称为“白盒”重用。如果基类改变了,子类的实现也必须改变。从基类继承的实现是静态的,不能在运行时更改,并且不够灵活。此外,继承只能在有限的环境中使用(例如,没有声明一个类不能被继承)。

发展

对于继承的深刻理解,可以参考《软件架构设计》的作者虞雯写的文章—— 《见山只是山见水只是水——提升对继承的认识》。

因为组合或聚合关系可以将现有对象(也称为成员对象)合并到新对象中,并使其成为新对象的一部分,所以新对象可以调用现有对象的函数,这可以使成员对象的内部实现细节对新对象不可见。所以,这种复用也叫“黑箱”复用。与继承关系相比,其耦合度相对较低,成员对象的变化对新对象影响不大。合成可以在运行时动态完成,新对象可以动态引用与成员对象相同类型的其他对象。

一般来说,如果两个类之间的关系是“Has-A”,就应该用组合或者聚合,如果是“Is-A”,就可以用继承。“Is-A”是一个严格的分类学定义,意思是一个类是另一个类的“一种”;和“有-有”不同,它意味着某个角色有一定的责任。

下面是一个简单的例子来加深对复合复用原理的理解:

在Sunny Software公司早期的CRM系统设计中,考虑到客户数量少,系统使用MySQL作为数据库,需要将CustomerDAO类等与数据库操作相关的类连接到数据库,将连接数据库的方法getConnection()封装在DBUtil类中。由于需要重用DBUtil类的getConnection()方法,设计人员将CustomerDAO作为DBUtil类的子类,初步设计方案结构如图1所示。

图1初步设计方案结构图。

随着客户数量的增加,系统决定升级到Oracle数据库,因此需要添加一个新的OracleDBUtil类来连接Oracle数据库。由于在最初的设计方案中,CustomerDAO和DBUtil之间存在继承关系,所以在改变数据库连接方式时,需要修改CustomerDAO类的源代码,将CustomerDAO做成OracleDBUtil的子类,这样会违反开闭原则。【当然也可以修改DBUtil类的源代码,这样也会违反开闭原则。】

现在利用复合复用的原理进行重构。

按照复合复用的原则,在实现复用时要多关联少继承。因此,在这个例子中,我们可以使用关联复用代替继承复用,重构后的结构如图2所示:

图2改造后的结构图。

在图2中,CustomerDAO和DBUtil之间的关系从继承变为关联,DBUtil对象通过依赖注入注入到CustomerDAO中,或者通过构造注入,或者通过Setter注入。如果需要扩展DBUtil的功能,可以通过它的子类来实现,比如通过子类OracleDBUtil连接Oracle数据库。由于CustomerDAO是为DBUtil编程的,根据Richter替换原理,DBUtil子类的对象可以覆盖DBUtil对象,子类扩展的方法只能通过将子类注入CustomerDAO来使用。比如通过将OracleDBUtil对象注入CustomerDAO,可以实现Oracle数据库连接,不需要修改原代码,可以灵活添加新的数据库连接方式。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/70037.html

(0)

相关推荐

  • 志趣的意思,你是如何理解志趣相投的

    技术志趣的意思,你是如何理解志趣相投的臭味相投的常见,比如麻将馆里的人,上了牌桌都成了相差无几的德性志趣的意思。志趣相投的人,要么是做同一样工作,就是团队精神吧。要么是经商共赢的人,就是齐心协力吧。但是越有文化知识的人越

    生活 2021年10月19日
  • abab的词语,abab的形容词语有哪些

    技术abab的词语,abab的形容词语有哪些ABAB没有成语,词语有不少,列举如下abab的词语: 努力努力 享受享受 了解了解 打探打探 打听打听 分析分析 娱乐娱乐 紧张紧张 暖和暖和 凉快凉快 学习学习 精神精神

    生活 2021年10月25日
  • CAS存在哪些问题

    技术CAS存在哪些问题本篇内容主要讲解“CAS存在哪些问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CAS存在哪些问题”吧!1、循环+CAS,自旋的实现让所有线程处于高频

    攻略 2021年11月16日
  • 在html5中头部包含哪个元素结构(html5头部内容通常包括哪个元素)

    技术html5头部内容通常包括什么内容这篇文章主要介绍html5头部内容通常包括什么内容,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! html5头部内容通常包括:1、

    攻略 2021年12月17日
  • Android对Linux系统的内存管理机制进行的优化是什么

    技术Android对Linux系统的内存管理机制进行的优化是什么这篇文章主要介绍“Android对Linux系统的内存管理机制进行的优化是什么”,在日常操作中,相信很多人在Android对Linux系统的内存管理机制进行

    攻略 2021年11月30日
  • 如何进行MongoDB查询文档

    技术如何进行MongoDB查询文档如何进行MongoDB查询文档,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。查询文件使用inventory集合。插入inv

    攻略 2021年11月4日