"合成聚合复用原则" (转http://www.cnblogs.com/supertbt/archive/2007/03/07/666319.html)
来源:互联网 发布:知己知彼软件怎么样 编辑:程序博客网 时间:2024/06/17 03:38
走想设计5--"合成聚合复用原则"
合成(Composition)和聚合(Aggregation)都是关联(Association)的特殊种类。聚合表示整体和部分的关系,表示“拥有”;合成则是一种更强的“拥有”,部分和整体的生命周期一样。合成的新的对象完全支配其组成部分,包括它们的创建和湮灭等。一个合成关系的成分对象是不能与另一个合成关系共享的。
换句话说,合成是值的聚合(Aggregation by Value),而一般说的聚合是引用的聚合(Aggregation by Reference)。
简短的说,合成-聚合复用原则(CARP)是指,尽量使用合成/聚合,而不是使用继承。
在OOD中,有两种基本的办法可以实现复用,一种是通过合成/聚合,另外一种就是通过继承。通过合成/聚合的好处是:
- 新对象存取成分对象的唯一方法是通过成分对象的接口。
- 这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。
- 这种复用支持包装。
- 这种复用所需的依赖较少。
- 每一个新的类可以将焦点集中在一个任务上。
- 这种复用可以在运行时间内动态进行,新对象可以动态的引用与成分对象类型相同的对象。
- 作为复用手段可以应用到几乎任何环境中去。
它的缺点就是系统中会有较多的对象需要管理。
通过继承来进行复用的优点是:
- 新的实现较为容易,因为超类的大部分功能可以通过继承的关系自动进入子类。
- 修改和扩展继承而来的实现较为容易。
缺点是:
- 继承复用破坏包装,因为继承将超类的实现细节暴露给子类。由于超类的内部细节常常是对于子类透明的,所以这种复用是透明的复用,又称“白箱”复用。
- 如果超类发生改变,那么子类的实现也不得不发生改变。
- 从超类继承而来的实现是静态的,不可能在运行时间内发生改变,没有足够的灵活性。
- 继承只能在有限的环境中使用。
要正确的选择合成/复用和继承,必须透彻的理解里氏代换原则和Coad法则。里氏代换原则前面学习过,Coad法则由Peter Coad提出,总结了一些什么时候使用继承作为复用工具的条件。只有当以下的Coad条件全部被满足时,才应当使用继承关系:
- 子类是超类的一个特殊种类,而不是超类的一个角色,也就是区分“Has-A”和“Is-A”。只有“Is-A”关系才符合继承关系,“Has-A”关系应当用聚合来描述。
- 永远不会出现需要将子类换成另外一个类的子类的情况。如果不能肯定将来是否会变成另外一个子类的话,就不要使用继承。
- 子类具有扩展超类的责任,而不是具有置换调(override)或注销掉(Nullify)超类的责任。如果一个子类需要大量的置换掉超类的行为,那么这个类就不应该是这个超类的子类。
- 只有在分类学角度上有意义时,才可以使用继承。不要从工具类继承。
错误的使用继承而不是合成/聚合的一个常见原因是错误的把“Has-A”当成了“Is-A”。“Is-A”代表一个类是另外一个类的一种;“Has-A”代表一个类是另外一个类的一个角色,而不是另外一个类的特殊种类。
我们看一个例子。如果我们把“人”当成一个类,然后把“雇员”,“经理”,“学生”当成是“人”的子类。这个的错误在于把“角色”的等级结构和“人”的等级结构混淆了。“经理”,“雇员”,“学生”是一个人的角色,一个人可以同时拥有上述角色。如果按继承来设计,那么如果一个人是雇员的话,就不可能是经理,也不可能是学生,这显然不合理。正确的设计是有个抽象类“角色”,“人”可以拥有多个“角色”(聚合),“雇员”,“经理”,“学生”是“角色”的子类。
另外一个就是只有两个类满足里氏代换原则的时候,才可能是“Is-A”关系。也就是说,如果两个类是“Has-A”关系,但是设计成了继承,那么肯定违反里氏代换原则。
- "合成聚合复用原则" (转http://www.cnblogs.com/supertbt/archive/2007/03/07/666319.html)
- http://www.cnblogs.com/MaxWoods/archive/2007/04/07/704038.html
- HashMap按key排序(http://www.cnblogs.com/kentyshang/archive/2007/07/04/805397.html)
- http://www.cnblogs.com/zc22/archive/2007/12/07/986978.html
- QQ机器人 http://www.cnblogs.com/sukyboor/archive/2007/01/03/610451.html
- http://www.cnblogs.com/scdsun/archive/2007/03/27/681326.html
- .Net Remoting (转载)(转自http://www.cnblogs.com/JimmyZhang/archive/2008/07/26/1252183.html)
- winform 窗体传值 转http://www.cnblogs.com/kivenhou/archive/2010/09/07/1820950.html
- jQuery动态表格(转自:http://www.cnblogs.com/Zjmainstay/archive/2012/07/12/jQuery_autoAddDeleteTableTr.html)
- tar命令(转自http://www.cnblogs.com/qq78292959/archive/2011/07/06/2099427.html)
- 转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html
- Snmp学习笔记 (转) http://www.cnblogs.com/jambol/archive/2007/08/30/875366.html
- 转之:http://www.cnblogs.com/sopper/archive/2007/06/15/784947.html
- 敏捷开发(转自:http://www.cnblogs.com/blusehuang/archive/2007/10/17/926802.html)
- 【转】http://www.cnblogs.com/springyangwc/archive/2011/03/30/2000388.html
- c#的迭代器,转自http://www.cnblogs.com/yangecnu/archive/2012/03/17/2402432.html
- GCC 编译选项(转)http://www.cnblogs.com/xmphoenix/archive/2011/03/21/1989944.html
- 转自http://www.cnblogs.com/dirichlet/archive/2011/03/16/1986251.html
- linux操作系统原理与应用-读书笔记(2)-进程(1)
- 计算一个语句产生的undo
- new、vitual、override之间那点事
- 郁闷了,硬件和软件
- inet_ntoa 连续使用 注意事项
- "合成聚合复用原则" (转http://www.cnblogs.com/supertbt/archive/2007/03/07/666319.html)
- 安全保密级别高的环境下部署Silverlight应用程序
- Hibernate数据不能插入同时也没有报错
- 母版页中引用图片、外部js、css文件的路径问题
- 错误提示:ORA-01747: user.table.column, table.column 或列说明无效
- 个人能力
- 迅时网关资料整理 MX8 MX51 FXO FXS 等等
- matlab批量操作
- 学生成绩管理查询系统