合成聚合原则
1.定义
合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下:尽量使用对象组合,而不是继承来达到复用的目的。合成复用原则就是在一个新的对象里通过关联关系(包括组合关系和聚合关系)来使用一些 已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用功能 的目的。简言之:复用时要尽量使用组合/聚合关系(关联关系),少用继承。
2.合成与聚合的区别
2.1合成
表示一个整体与部分的关系,指一个依托整体而存在的关系(整体与部分不可以分开),虽然组合表示的是一个整体与部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在,部分对象与整体对象之间具有同生共死的关系。例如:一只鸟对他的翅膀,它的翅膀是不能被共享,因为翅膀是它自己的。并且鸟没了,这个也关系就没了。在组合关系中,成员类是整体类的一部分,而且整体类可以控制成员类的生命周期,即成员类的存在依赖于整体类。在UML中,组合关系用带实心菱形的直线表示。

public class Bird{ private Wing wing; public Bird() { wing = new Wing(); } } public class Wing{ //......... }
2.2聚合
聚合是比合成关系更弱的一种拥有关系,也表示整体与部分的关系(整体与部分可以分开),通常在定义一个整体类后,再去分析这个整体类的组成结构,从而找出一些成员类,该整体类和成员类之间就形成了聚合关系。在聚合关系中,成员类是整体类的一部分,即成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在。 例如,一辆特定汽车对专门供他使用的引擎和轮胎的关系就是带有聚合性质的。因为引擎和轮胎他们只能被该类汽车所用,离开了该辆汽车,它们就失去了存在的意义。在UML中,聚合关系用带空心菱形的直线表示。

public class Car { private Engine engine; public Car(Engine engine) { this.engine = engine; } public void setEngine(Engine engine) { this.engine = engine; } } public class Engine { //...... }
3.合成聚合原则的使用
3.1使用“Has-A”和“Is-A”来推断
"Is-A"是严格的分类学意义上的定义,意思是一个类是另一个类的“一种”。“Has-A”则不同,他表示某一个角色具有某一项责任。如果是“Is-A”关系就用继承来实现,如果是“Has-A”关系就用合成聚合原则实现。例如下图实例的关系中人和角色的关系就是“Has-A”关系。

3.2与里氏代换原则联合使用
里氏代换原则是继承复用的基石。如果在任何使用B类型的地方都可以使用S类型。那么S类型才能称为B类型的子类型,而B类型才能称为S类型的基类型。换言之,只有当每一个S在任何情况下都是一种B的时候,才可以将S设计成为B的子类。如果两个类的关系是“Has-A”关系而不是“Is-A”关系,这两个类一定违反里氏代换原则。
4.合成聚合原则的作用
可以使系统更加灵活,类与类之间的耦合度降低,一个类的变化对其他类造成的影响相对较少,因此一般首选使用组合/聚合来实现复用;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。
参考链接:https://blog.csdn.net/liaoqianchuan00/article/details/8230459
https://www.bbsmax.com/A/xl5690BoJr/
《java设计模式》
《java与模式》

浙公网安备 33010602011771号