设计模式-原则-组合复用原则

转载:

 

组合复用原则

定义

组合复用原则经常又叫做合成复用原则。该原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分:新的对象通过向这些对象的委派达到复用已有功能的目的。

而在我们的代码中尽可能使用组合而不是用继承是什么原因呢?

原因如下

  • 第一,继承复用破坏包装,它把父类的实现细节直接暴露给了子类,这违背了信息隐藏的原则;

  • 第二:如果父类发生了改变,那么子类也要发生相应的改变,这就直接导致了类与类之间的高耦合,不利于类的扩展、复用、维护等,也带来了系统僵硬和脆弱的设计。而用合成和聚合的时候新对象和已有对象的交互往往是通过接口或者抽象类进行的,就可以很好的避免上面的不足,而且这也可以让每一个新的类专注于实现自己的任务,符合单一职责原则。

其实这个组合复用原则最好的理解就是我们各种系统中的后台系统里面的权利和角色的分配,我相信很多公司的项目中都会有,我来阐述一下这个问题。

“Has-A”和“Is-A”

“Is-A”是严格的分类学意义上的定义,意思是一个类是另外一个类的“一种”。而“Has-A”则不同,他表示某一个角色具有某一项责任。

我们看一个图解

 

人被继承到“雇员”,“经理”,“学生”等子类,而实际上,“雇员”,“经理”,“学生”分别描述一种角色,而“人”可以同时有几种不同的角色,比如,一个“人”即使“经理”,就必然是“雇员”,而有可能这个“人”还是一个“学生”。如果说使用继承来说,那么如果这个人是“学生”,那么它一定不能再是经理,这个大家可以思考一下为什么,很简单,这显然就是不合理的。

 

图中的这种就是把“角色”的等级结构和“人”的等级结构混淆了,把“Has-A”角色误解成为了“Is-A”角色,而下面这幅图就成功的解释了这一点

 

而在这个图中,就不存在之前混淆的问题了,每个人都可以拥有一个以上的“角色”了。

 

组合/聚合复用原则使用总结:

合成和聚合均是关联的特殊情况。聚合用来表示“拥有”关系或者整体与部分的关系;而合成则用来表示一种强得多的“拥有”关系。在一个合成关系里面,部分和整体的生命周期是一样的。一个合成的新的对象完全拥有对其组成部分的支配权,包括它们的创建和销毁等。使用程序语言的术语来说,组合而成的新对象对组成部分的内存分配、内存释放有绝对的责任。要正确的选择合成/复用和继承,必须透彻地理解里氏替换原则和Coad法则。(Coad法则由Peter Coad提出,总结了一些什么时候使用继承作为复用工具的条件。Coad法则:只有当以下Coad条件全部被满足时,才应当使用继承关系)

 

1. 子类是基类的一个特殊种类,而不是基类的一个角色。区分“Has-A”和“Is-A”。只有“Is-A”关系才符合继承关系,“Has-A”关系应当用聚合来描述。 

 

2. 永远不会出现需要将子类换成另外一个类的子类的情况。如果不能肯定将来是否会变成另外一个子类的话,就不要使用继承。 

 

3. 子类具有扩展基类的责任,而不是具有置换掉(override)或注销掉(Nullify)基类的责任。如果一个子类需要大量的置换掉基类的行为,那么这个类就不应该是这个基类的子类。 

 

4. 只有在分类学角度上有意义时,才可以使用继承。不要从工具类继承。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值