合成(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”关系,但是设计成了继承,那么肯定违反里氏代换原则。
分享到:
相关推荐
合成聚合复用原则,简称CARP或CRP,是面向对象设计中的一项重要原则,它强调在构建新对象时应优先考虑使用已有对象的合成和聚合,而不是通过继承来达到复用目的。这一原则旨在降低类之间的耦合度,提高系统的可维护...
合成聚合复用原则 合成聚合复用原则(Composition/Aggregate Reuse Principle, CARP)是一种面向对象设计原则,旨在指导开发者在设计中如何复用已有的对象。该原则强调在复用时,应该尽量使用组合/聚合关系,而不是...
java八股文
合成复用原则(Composite Reuse Principle,CRP),又称组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP),是在面向对象设计中的一项重要指导原则。该原则强调:在进行软件复用时,应优先考虑使用...
这六个原则分别是单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、合成聚合复用原则和接口隔离原则。这些原则可以帮助我们在面向对象编程中设计出更加合理、灵活、易于扩展和维护的系统。 1. 单一职责...
7. 对象适配器模式是合成聚合复用原则(A)的应用,允许不兼容的接口之间进行协作。 8. 静态工厂的核心角色是静态工厂(C),用于创建对象。 9. 静态工厂的错误表述是A,因为它通常通过if-else语句创建对象,这在...
- 合成聚合复用原则强调应尽量使用对象组合,而不是类继承。 - 接口隔离原则主张建立单一功能的小接口,而不是大而全的接口。 - 迪米特法则(最少知识原则)则建议一个对象应当对其他对象有尽可能少的了解。 最后,...
合成聚合复用原则推荐优先使用组合/聚合,而不是继承,以减少耦合。迪米特法则主张减少实体之间的交互,只与直接相关的实体通信。 接下来,我们将会学习一系列经典的设计模式,如简单工厂模式、工厂方法模式、抽象...
13. **对象适配器模式**:体现了合成聚合复用原则(A),通过组合的方式实现接口适配。 14. **静态工厂**的核心是静态工厂类(C),它创建产品对象。 15. **静态工厂与工厂方法**:静态工厂以if/else或其他逻辑...
13. **对象适配器模式**:它是合成聚合复用原则的典型应用(选A),允许不兼容的接口之间进行通信。 14. **静态工厂的核心角色**:静态工厂方法的核心角色是静态工厂(选C),它负责创建产品对象。 15. **静态工厂...
13. 对象适配器模式应用了合成聚合复用原则(A选项)。 14. 静态工厂的核心角色是静态工厂(C选项),负责创建产品。 15. 静态工厂的错误表述是(A选项),因为它可以通过增加新的静态方法来满足开闭原则,而不...
Android的开发应用原则附加情景 对接口编程---问世间情为何物_直教人 开放封闭原则_孙悟空任弼马温一职 米特法则_慈禧太后为何不和陌生人 ...六合成聚合复用原则_刘邦VS韩信 四里氏代换原则_法海捉拿白蛇新解
5. **合成聚合复用原则**:优先使用对象的组合/聚合,而不是继承来实现功能的复用,以减少类间的耦合。 6. **迪米特法则(最少知识原则)**:一个对象应该尽量少地了解其他对象的内部细节,只和朋友交流,不和...
面向对象设计原则是OOPS(Object-Oriented ...这些原则已知的有七个,包括:单一职责原则、开闭原则、里氏代换原则、依赖注入(倒转)原则、接口分离原则、迪米特原则、合成聚合复用原则。(文件包括实例源码及文档)
对象适配器模式是合成聚合复用原则(A) 的典型应用。它通过将一个类包装在另一个类中来实现适配,而不是通过继承来修改类的行为。 ### 14. 静态工厂的角色 静态工厂的核心角色是抽象产品(A)。静态工厂模式通过静态...
软件设计模式知识点 软件设计模式是解决软件设计问题的一种方法,旨在提高软件系统的灵活性、可维护性和可重用性。软件设计模式可以分为三类:...7. 合成聚合复用原则(CARP):优先使用对象合成/聚合,而不是类继承。
**合成聚合复用原则** - 当需要复用现有类的功能时,应优先使用组合或聚合,而不是通过继承来实现。 - **应用实例**:一个`Computer`类可以通过组合`Keyboard`、`Mouse`和`Monitor`类来实现其功能,而不是继承这些类...
6. **合成聚合复用原则** - “刘邦 VS 韩信”:优先使用组合或聚合来实现多态,而不是继承,以提高代码的灵活性和可维护性。 7. **简单工厂模式** - “一见钟情的代价”:提供一个静态方法来创建对象,简化客户端...
6. **合成聚合复用原则**:X邦与韩信的故事表明,优先使用组合或聚合而不是继承,以保持对象之间的松散耦合。 7. **简单工厂模式**:如“一见钟情的代价”,提供一个静态方法来创建对象,简化客户端代码。 8. **...