设计模式系列之设计原则(7)合成复用原则(组合/聚合复用原则)

定义

在软件设计过程中,类间关系优先使用组合关系或聚合关系,其次使用继承关系。

对于类的复用,分为合成复用和继承复用,两者都为适应需求变化,对系统进行扩展。合成复用原则强调合成关系的重要性,但并不否定继承关系。只是为达到低耦合系统的目标出发,合成带来的优势比继承更大。两者的优缺点对比如下。

继承复用主要存在以下优缺点:

  • 优点
    • 简单易实现
  • 缺点
    • 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为“白箱”复用。
    • 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护。
    • 它限制了复用的灵活性。从父类继承而来的实现是静态的,在编译时已经定义,所以在运行时不可能发生变化。

合成复用的优缺点:

  • 优点
    • 将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能。
    • 维持了类的封装性。因为成分对象的内部细节是新对象看不见的,所以这种复用又称为“黑箱”复用。
    • 新旧类之间的耦合度低。这种复用所需的依赖较少,新对象存取成分对象的唯一方法是通过成分对象的接口
    • 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。
  • 缺点
    • 需要许多中间类或接口,存在类爆炸风险,降低系统的可读性和可维护性。

作用

  • 合成复用原则的名称包含了该原则的主要作用,即达到复用的目的。
  • 开闭原则的重要实现方式之一。里氏替换原则利用继承实现开闭原则,合成复用原则利用合成实现开闭原则,两者都提高系统的可扩展性。
  • 降低类间的耦合,提高类的独立性。

实现方法

合成复用原则的名称包含了该原则的实现方法,即利用合成达到复用,合成包括组合和聚合。

代码实践

在设计类间关系时,首先要分析业务,判断使用继承关系是否合适。确定可以使用之后,要严格遵循里氏替换原则。

以下代码是采用继承关系实现功能,每当出现新的业务,就需要修改父类内容,违反了开闭原则。

//父类
public class FatherCourse {
    public String printJavaMenu(){
        return "java课程目录";
    }
    public String printPythonMenu(){
        return "python课程目录";
    }
}

//子类
public class Tyler  extends FatherCourse{
    public void getQueryMenu(){
        System.out.println("获取java" + super.printJavaMenu());
    }
}

//应用客户端
public class Test {
    public static void main(String[] args) {
        Tyler g = new Tyler();
        g.getQueryMenu();
    }
}

采用组合方式实现上述功能,其类图产生的效果类似依赖倒置原则的中例子,依赖发生反转。

//接口
public interface ICourse {
     void printMenu();
}

//接口实现类1
public class JavaCourse implements ICourse {
    @Override
    public void printMenu() {
        System.out.println("tyler在学习java课程");
    }
}

//接口实现类2
public class PythonCourse implements ICourse{
    @Override
    public void printMenu() {
        System.out.println("tyler在学习python课程");
    }
}

//使用接口的中间类
public class Tyler {
    public void getQueryMenu(ICourse iCourse){
        iCourse.printMenu();
    }
}

//应用客户端
public class Test {
    public static void main(String[] args) {
        Tyler tyler = new Tyler();
        tyler.getQueryMenu(new JavaCourse());
        tyler.getQueryMenu(new PythonCourse());
    }
}

相关知识点

  • 类间关系

    英文含义的逻辑方向跟uml中类图的箭头的指向一致,譬如 A is-a B,对应的UML图是 A—>B(此处应是三角箭头),即由A指向B。

    • 继承 is-a
    • 组合 contains-a
    • 聚合 has-a
    • 依赖 use-a

参考资料

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值