软件设计原则-合成复用原则讲解以及代码示例

简介: 合成复用原则(Composition/Aggregation Reuse Principle,CARP)是面向对象设计的一种重要原则,也被称为组合/聚合复用原则。它强调通过组合(Composition)或聚合(Aggregation)关系来达到代码复用的目的,而不是通过继承关系。

 合成复用原则

一,介绍

1.前言

合成复用原则(Composition/Aggregation Reuse Principle,CARP)是面向对象设计的一种重要原则,也被称为组合/聚合复用原则。它强调通过组合(Composition)或聚合(Aggregation)关系来达到代码复用的目的,而不是通过继承关系。

合成复用原则的核心思想是尽量使用对象之间的弱关联关系(组合或聚合关系),而不是使用强关联关系(继承关系)。强关联关系(继承关系)会导致高度耦合的代码,并可能引入不必要的继承层次、复杂性和脆弱性。而弱关联关系(组合或聚合关系)可以降低类之间的依赖程度,使系统更加灵活、可维护和可扩展。

合成复用原则的优点在于:

1. 降低类之间的耦合度,提高系统的灵活性。通过组合或聚合关系,可以将功能模块拆分成独立的对象,各自负责不同的功能,从而减少了类之间的直接依赖关系,使得系统的各个模块可以相对独立地变化和演化。

2. 提高代码的重用性。通过将公共的功能封装成独立的对象,可以在不同的场景中重复利用这些对象,避免了重复编写相似的代码,提高了代码的复用性和可读性。

3. 支持动态组合和配置。由于弱关联关系的灵活性,可以在运行时通过动态组合和配置对象来实现不同的功能组合,从而满足不同的需求。

合成复用原则的实现主要有以下几种方式:

1. 组合关系(Composition):通过将一个类对象嵌入到另一个类中作为其成员变量来实现复用。被嵌入的对象可以通过接口暴露出一部分功能,供外部使用。

2. 聚合关系(Aggregation):通过将一个类对象作为另一个类的成员变量,并且两者之间存在一种“整体-部分”的关系来实现复用。被聚合的对象可以拥有自己的独立生命周期,可以在多个不同的上下文中共享。

3. 接口复用:通过定义通用的接口,并让多个类去实现这个接口来实现复用。其他类可以通过调用接口方法来使用这些功能。

2.何时使用合成复用原则

1. 需要在运行时动态组合对象:如果系统需要在运行时根据特定需求动态组合对象,而不是在编译时确定对象的结构和行为,那么可以使用合成复用原则。通过组合或聚合多个对象,可以灵活地配置和创建复杂的对象结构。

2. 避免类之间的紧耦合关系:继承会导致类之间的紧耦合关系,当父类发生变化时,子类也会受到影响。而合成复用原则通过对象组合或聚合来实现代码复用,减少了类之间的依赖关系,使得系统更加灵活、可维护和易于扩展。

3. 需要灵活地改变对象的部分行为:使用继承来复用代码会限制对象的行为,并且难以灵活地改变对象的部分行为。而合成复用原则通过对象组合或聚合的方式,可以动态地改变对象的组成部分,进而实现不同的行为组合。

4. 需要避免多层次的继承体系:多层次的继承体系会增加系统的复杂性和维护成本。如果系统中存在多个类之间的复用关系,而这些类之间又存在继承关系,那么可以考虑使用合成复用原则来简化继承体系,减少继承链的长度。

需要注意的是,合成复用原则并不意味着完全放弃继承,而是在选择代码复用的方式时更倾向于对象组合或聚合。在具体应用中,要根据设计需求、系统架构和可维护性等因素综合考虑,灵活运用合成复用原则和继承机制来实现代码的复用和设计的优化。

二,代码示例

下面以一个简单的例子来说明合成复用原则:

public interface Engine {
    void start();
    void stop();
}
public class GasolineEngine implements Engine {
    public void start() {
        System.out.println("Gasoline engine starts.");
    }
    public void stop() {
        System.out.println("Gasoline engine stops.");
    }
}
public class ElectricEngine implements Engine {
    public void start() {
        System.out.println("Electric engine starts.");
    }
    public void stop() {
        System.out.println("Electric engine stops.");
    }
}
public class Car {
    private Engine engine;
    public Car(Engine engine) {
        this.engine = engine;
    }
    public void start() {
        engine.start();
    }
    public void stop() {
        engine.stop();
    }
}

image.gif

在这个例子中,定义了一个抽象的`Engine`接口,包含了汽车引擎的启动和停止方法。然后分别实现了两个具体的引擎类:`GasolineEngine`和`ElectricEngine`。接着定义了一个`Car`类,其构造函数接收一个引擎对象,并持有该引擎对象作为成员变量。`Car`类通过调用引擎对象的方法实现汽车的启动和停止功能。

这个设计遵循了合成复用原则。`Car`类与`Engine`之间并不是继承关系,而是通过组合关系来实现复用。`Car`类可以与不同类型的引擎进行组合,从而实现不同类型的汽车。如果需要新增一种引擎类型,只需实现对应的引擎类,并传入`Car`类的构造函数即可,不需要修改`Car`类的代码。

总之,合成复用原则强调通过组合或聚合关系来实现代码的复用,而不是过度依赖继承关系。通过遵循合成复用原则,可以降低类之间的耦合度,提高系统的灵活性、可维护性和可扩展性,并且支持动态组合和配置功能。

三,优缺点

合成复用原则(Composition/Aggregation Reuse Principle)是一种面向对象设计的原则,它强调通过对象组合或聚合来实现代码复用,而不是通过继承。合成复用原则具有以下优点和缺点:

优点:

1. 灵活性和可扩展性:通过对象组合或聚合,可以动态地创建和配置对象的结构,使系统更加灵活、可扩展和易于维护。不再受限于继承体系的静态结构,可以根据需求灵活地组合和替换对象。

2. 降低耦合度:使用合成复用原则可以降低类之间的紧耦合关系。对象之间的依赖关系更加松散,一个对象的变化不会直接影响其他对象,减少了系统的耦合度,提高了代码的独立性和可维护性。

3. 提高代码复用性:通过对象组合或聚合,可以将通用的功能封装在独立的对象中,并在多个地方进行复用。不同的对象可以以不同的方式组合,实现更灵活的代码复用,避免了继承可能带来的局限性。

4. 满足“面向接口编程”原则:合成复用原则鼓励使用接口来描述对象之间的协作关系,而不是依赖于具体的实现。通过接口的规范,可以更好地解耦对象之间的关系,提高系统的可维护性和可扩展性。

缺点:

1. 增加了对象间通信的复杂性:使用合成复用原则可能引入更多的对象,导致对象间的通信和交互变得更加复杂。需要设计良好的接口和协议来确保对象之间的协作正确无误。

2. 需要更多的设计和配置工作:相比继承,使用合成复用原则需要更多的设计和配置工作。需要考虑对象的组合方式、接口的定义与实现等方面,增加了开发人员的工作量和设计成本。

3. 可能引入过多的中间层级:为了实现对象的组合或聚合,可能需要引入额外的中间对象。这可能导致系统结构的复杂化和性能的降低。

总结起来,合成复用原则通过灵活的对象组合或聚合来实现代码的复用,提高了系统的灵活性、可扩展性和代码的独立性。然而,使用合成复用原则需要考虑对象间通信的复杂性、增加的设计和配置工作,以及可能引入的中间层级等问题。在具体应用中,需要根据实际情况权衡利弊,选择合适的设计方案。

目录
相关文章
|
7月前
|
测试技术
软件设计原则-单一置原则讲解以及代码示例
单一职责原则(Single Responsibility Principle,SRP)是面向对象设计中的一个重要原则,提倡将一个类或模块只负责一个职责或功能。它最早由Robert C. Martin在其《敏捷软件开发:原则、模式与实践》一书中提出。 单一职责原则的核心思想是:一个类或模块应该只有一个引起它变化的原因。也就是说,每个类或模块都应该只有一个职责或功能,并且该职责或功能应该在该类或模块内部封装起来,而不是分散到多个类或模块中。
36 0
|
7月前
软件设计原则-接口隔离原则讲解以及代码示例
接口隔离原则(Interface Segregation Principle,ISP)是面向对象设计中的一个原则,提倡使用多个专门的接口,而不使用单一的大接口。它最早由Robert C. Martin在其《敏捷软件开发:原则、模式与实践》一书中提出。 接口隔离原则的核心思想是:客户端不应该依赖于它不需要的接口。也就是说,一个类或模块不应该强迫它的用户去依赖无用的接口。相反,应该将大接口拆分成多个小接口,符合客户端的需求,使客户端只依赖于它真正需要的接口。 接口隔离原则的目标是降低类或模块之间的耦合度,提高代码的可维护性、可扩展性和可测试性。通过使用多个专门的接口,我们可以避免类或模块之间出现不
34 0
|
7月前
|
测试技术 数据库
软件设计原则-依赖倒置原则讲解以及代码示例
依赖倒置原则(Dependency Inversion Principle,DIP)是面向对象设计中的一个重要原则,由Robert C. Martin提出。 依赖倒置原则的核心思想是:高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现细节,而具体实现细节应该依赖于抽象。这意味着我们在进行系统设计时,应该尽量使用抽象类或接口来定义对象之间的依赖关系,而不是直接依赖于具体的实现类
146 0
|
7月前
|
设计模式 Java
Java设计模式七大原则-合成聚合复用原则
Java设计模式七大原则-合成聚合复用原则
55 0
|
7月前
合成复用原则~
合成复用原则~
|
8月前
|
设计模式 Oracle 关系型数据库
七大设计原则之合成复用原则应用
七大设计原则之合成复用原则应用
116 0
|
9月前
|
设计模式 Oracle 关系型数据库
软件架构设计原则之合成复用原则
合成复用原则(Composite/Aggregate Reuse Principle,CARP)是指尽量使用对象组合(has-a)/聚合(contanis-a)而不是继承关系达到软件复用的目的。可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。
82 0
|
设计模式 测试技术 程序员
代码的简单设计五原则
代码的简单设计五原则
33036 1
|
设计模式
设计模式(7) -- 合成复用原则和七大原则总结
设计模式(7) -- 合成复用原则和七大原则总结
106 0
设计模式(7) -- 合成复用原则和七大原则总结
|
设计模式 Oracle 关系型数据库
软件架构设计原则--合成复用原则
本专栏内容参考自:咕泡学院Tom老师的《Spring5核心原理与30个类手写实战》,仅作个人学习记录使用,如有侵权,联系速删