合成聚合原则

组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP).组合和聚合都是对象建模中关联(Association)关系的一种.聚合表示整体与部分的关系,表示“含有”,整体由部分组合而成,部分可以脱离整体作为一个独立的个体存在。组合则是一种更强的聚合,部分组成整体,而且不可分割,部分不能脱离整体而单独存在。在合成关系中,部分和整体的生命周期一样,组合的新的对象完全支配其组成部分,包括他们的创建和销毁。一个合成关系中成分对象是不能与另外一个合成关系共享。

  1. 合成/聚合复用

由于合成或聚合可以将已有对象纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能。这样做的好处有

(1) 新对象存取成分对象的唯一方法是通过成分对象的接口。

(2) 这种复用是黑箱复用,因为成分对象的内部细节是新对象看不见的。

(3) 这种复用支持包装。

(4) 这种复用所需的依赖较少。

(5) 每一个新的类可以将焦点集中到一个任务上。

(6) 这种复用可以再运行时间内动态进行,新对象可以动态地引用与成分对象类型相同的对象。

  1. 继承复用

继承复用通过扩展一个已有对象的实现来得到新的功能,基类明显的捕获共同的属性和方法,而子类通过增加新的属性和方法来扩展超类的实现。继承是类型的复用。

继承复用的优点。

(1) 新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。

(2) 修改或扩展继承而来的实现较为容易。

继承复用的缺点。

(1) 继承复用破坏包装,因为继承将超类的实现细节暴露给了子类。因为超类的内部细节常常对子类是透明的,因此这种复用是透明的复用,又叫“白箱”复用。

(2) 如果超类的实现改变了,那么子类的实现也不得不发生改变。因此,当一个基类发生了改变时,这种改变会传导到一级又一级的子类,使得设计师不得不相应的改变这些子类,以适应超类的变化。

(3) 从超类继承而来的实现是静态的,不可能在运行时间内发生变化,因此没有足够的灵活性。

  1. 需要注意一点的是,由于继承复用有以上的缺点,所以尽量使用合成/聚合而不是继承来达到对实现的复用,是非常重要的设计原则。只有当以下的条件全部被满足时,才应当使用继承关系:

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

 

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

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

  1. 例子

合成复用原则重构,重新定义 DBConnection, 修改为一个抽象类

public abstract class DBConnection2 {

public abstract String getConnection();}

增加Mysql实现

public class MySQLConnection extends DBConnection2 {

    @Override

    public String getConnection() {

        return "MySQL数据库连接";

    }

}

 

参考文献

https://www.jianshu.com/p/056d0c2d5470

https://www.cnblogs.com/shaosks/archive/2012/02/08/2342593.html

posted @ 2020-03-21 19:24  YTTerrellL  阅读(187)  评论(0)    收藏  举报