Java设计模式七大原则-合成聚合复用原则

简介: Java设计模式七大原则-合成聚合复用原则

合成-聚合复用原则

1、合成-聚合复用原则介绍


合成/聚合复用原则(Composition/Aggregation Reuse Principle,CARP)是一种面向对象设计原则,它提倡通过合成/聚合关系(组合关系)来达到代码复用的目的,而不是通过继承关系。


1.1 继承与组合对比

CARP 的基本思想是在设计类之间的关系时,优先选择合成/聚合关系,而不是继承关系。通过将对象组合在一起形成更大的对象,来达到复用的目的。


继承关系在某些情况下可能导致代码的耦合性增加,使得系统的灵活性和可维护性下降。


而合成 / 聚合关系则可以更加灵活地组合对象,使得系统的结构更加松散,各个对象之间的耦合度降低。


1.2 合成与聚合

聚合表示一种弱的 拥有 关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。


合成则是一种强的 拥有 关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。


比如说:


大雁有两个翅 膀,翅膀与大雁是部分和整体的关系,并且它们的生命周期是相同的,于是大雁和翅膀就是合成关系。而大雁是群居动物,所以每只大雁都是属于一个 雁群,一个雁群可以有多只大雁,所以大雁和雁群是聚合关系。


又比如:


合成和聚合是两种描述对象间关系的方式,合成表示整体包含部分,它的组成部分不能再单独存在,例如汽车由底盘,发动机,车身等构成。聚合则表示整体与部分之间是一

种“拥有”的关系,部分可以存在于整体之外,例如公司与员工之间的关系。

2、合成/聚合案例说明

假设我们有一个简单的图形绘制程序,需要绘制不同形状的图形,比如矩形和圆形。我们可以使用合成/聚合复用原则来设计这个程序。


2.1 使用合成/聚合复用原则


首先,让我们使用合成/聚合原则来实现这个例子。我们定义一个抽象类Shape,作为所有图形的基类,其中包含一个抽象方法draw()用于绘制图形。然后,我们创建两个具体类Rectangle和Circle,它们分别实现Shape类,并重写draw()方法来实现矩形和圆形的绘制逻辑。

// 图形抽象类:
abstract class Shape {
    public abstract void draw();
}
// 矩形绘制
class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
// 圆形绘制
class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

接下来,我们可以在绘制程序中使用这些图形类。我们创建一个Drawing类,其中包含一个drawShape()方法,它接收一个Shape对象,并调用draw()方法来绘制图形。

class Drawing {
    public void drawShape(Shape shape) {
        shape.draw();
    }
}


现在,我们可以使用以下代码来绘制矩形和圆形:

public class Main {
    public static void main(String[] args) {
        Shape rectangle = new Rectangle();
        Shape circle = new Circle();
        Drawing drawing = new Drawing();
        drawing.drawShape(rectangle);  // 绘制矩形
        drawing.drawShape(circle);     // 绘制圆形
    }
}


通过合成/聚合复用原则,我们通过将Drawing类与Shape类组合起来,实现了绘制程序的复用和灵活性。我们可以轻松地扩展程序,添加新的图形类,而不需要修改现有的代码。符合了开闭原则

2.2 不使用合成/聚合复用原则


现在,让我们看看如果不使用合成/聚合复用原则,直接使用继承关系来实现这个例子会出现什么问题。

class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
class Circle extends Rectangle {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}


在这个例子中,我们将圆形类直接继承自矩形类,这样的设计违反了合成/聚合复用原则。虽然代码看起来似乎工作正常,但这种设计存在一些问题。


首先,这种设计导致圆形与矩形之间存在不必要的继承关系。圆形并不是一种特殊的矩形,它们的行为和属性是不同的。这样的继承关系破坏了类的单一职责原则和 Liskov替换原则,增加了代码的复杂性和维护成本。


其次,如果我们想要添加其他形状,比如三角形或椭圆形,我们将不得不在继承关系中继续扩展,比如创建一个Triangle类继承自Shape,或者创建一个Ellipse类继承自Circle,这样的扩展会导致类的层级结构变得复杂,难以管理和扩展。


另外,使用继承关系来实现不同形状的绘制逻辑,限制了我们在运行时动态地改变图形的行为。例如,如果我们想要在运行时切换一个图形的绘制方式,使用继承关系就无法实现这种灵活性。


综上所述,如果不使用合成/聚合复用原则,直接使用继承关系来实现图形绘制程序,会导致类之间的耦合度增加,继承关系的滥用,限制了系统的灵活性和扩展性。而使用合成/聚合复用原则,通过组合对象,可以实现更松散的耦合,更灵活的设计和扩展,使得代码更易于维护和修改。

3、合成/聚合复用原则(CARP)的总结


合成/聚合复用原则的优点:


降低耦合性:通过使用合成/聚合关系而不是继承关系,可以减少类之间的依赖性,降低系统的耦合度。

提高灵活性:合成/聚合关系允许在运行时动态地组合对象,使得系统更加灵活,可以根据需要进行组合和重组。

支持扩展和修改:使用合成/聚合关系可以轻松地添加、修改或替换组件,而不会对现有的代码产生影响,提高了系统的可维护性和可扩展性。

遵循单一职责原则:合成/聚合关系使得每个类都可以专注于自己的职责,提高了类的内聚性和可读性。

合成/聚合复用原则的缺点:


增加代码复杂性:使用合成/聚合关系可能需要引入更多的类和接口,增加了代码的复杂性和理解成本。

需要更多的设计和管理:合成/聚合关系需要更加细致的设计和管理,以确保正确地组合和使用对象,否则可能导致不必要的复杂性和错误。

合成/聚合复用原则的适用场景:


当需要在运行时动态地组合和重组对象,或者需要支持灵活的配置和扩展时,合成/聚合复用原则是非常适用的。

当类之间的关系不是"is-a"的继承关系,而是"has-a"的组合关系时,使用合成/聚合关系更加合适。例如,部分-整体的关系、装饰器模式等场景都可以通过合成/聚合关系来实现。

总结来说,CARP原则通过合成/聚合关系来实现代码的复用和灵活性,相比于继承关系,它能够降低代码的耦合性,提高了系统的可维护性和可扩展性。然而,它也会增加代码的复杂性,需要更多的设计和管理。在需要动态组合对象、支持灵活配置和扩展的场景中,CARP原则是一个有价值的指导原则。


目录
相关文章
|
15天前
|
算法 Java Linux
java制作海报二:java使用Graphics2D 在图片上合成另一个照片,并将照片切割成头像,头像切割成圆形方法详解
这篇文章介绍了如何使用Java的Graphics2D类在图片上合成另一个照片,并将照片切割成圆形头像的方法。
29 1
java制作海报二:java使用Graphics2D 在图片上合成另一个照片,并将照片切割成头像,头像切割成圆形方法详解
|
3天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
12 0
[Java]23种设计模式
|
19天前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
2月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
2月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
15天前
|
算法 小程序 Java
java制作海报三:获取微信二维码详情,并改变大小,合成到海报(另一张图片)上
这篇文章介绍了如何使用Java获取微信小程序的二维码,并将其调整大小后合成到海报(另一张图片)上。
33 0
|
18天前
|
设计模式 Java
Java设计模式
Java设计模式
24 0
|
18天前
|
缓存 Java 数据库
JAVA分布式CAP原则
JAVA分布式CAP原则
43 0
|
21天前
|
设计模式 Java
Java设计模式之外观模式
这篇文章详细解释了Java设计模式之外观模式的原理及其应用场景,并通过具体代码示例展示了如何通过外观模式简化子系统的使用。
26 0
|
21天前
|
设计模式 Java
Java设计模式之桥接模式
这篇文章介绍了Java设计模式中的桥接模式,包括桥接模式的目的、实现方式,并通过具体代码示例展示了如何分离抽象与实现,使得两者可以独立变化。
36 0