【结构型模式】二十三天学会设计模式之装饰者模式

简介: 【结构型模式】二十三天学会设计模式之装饰者模式

一、什么是装饰者模式?

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

装饰者模式动态的给当前的对象增加一些别的功能,比子类模式更加的灵活,UML图如下所示:

ba505848295d42735028ee8316d91f7b.png

  • Component:抽象构件,定义一个对象接口,可以给这些对象动态地添加职责
  • ConreteComponent:一个具体对象,也可以给这个对象添加一些职责
  • Decorator:装饰抽象类,实现接口或抽象方法
  • ConreteDecorator:具体装饰对象,起到给Component添加职责的功能

二、为什么要用装饰者模式?

假如我们现在有一辆坦克,目前坦克只有移动功能。

我们想要这辆坦克拥有攻击、血条、尾巴、既有攻击又有血条、既有攻击又有尾巴等,子类实现模式如下:

我们可以看到,这种子类的实现模式有个缺点,如果我们对于当前坦克的附加功能过多,会造成大量的类臃肿。

有没有比较好的方法,既能实现我们的功能,还可以让类显得有条理、简洁性呢?

我们的装饰者模式解决这个问题的,不改变原有的类结构,通过装饰的作用让坦克额外的拥有攻击、血条、尾巴等功能。

三、如何实现装饰者模式?

我们参考上面的坦克例子,给出其结构图:

Tank:

public abstract class Tank {
    // 操作
    public abstract void operation();
}

BaseTank:

public class BaseTank extends Tank {
    @Override
    public void operation() {
        System.out.println("我拥有移动的功能");
    }
}

TankDecorator:

public class TankDecorator extends Tank {
    private Tank tank;
    @Override
    public void operation() {
        if (tank != null) {
            tank.operation();
        }
    }
    public TankDecorator(Tank tank) {
        this.tank = tank;
    }
}

AttackTankDecorator:

public class AttackTankDecorator extends TankDecorator {
    public AttackTankDecorator(Tank tank) {
        super(tank);
    }
    public void attack() {
        System.out.println("我拥有攻击的功能");
    }
    @Override
    public void operation() {
        attack();
        super.operation();
    }
}

TailTankDecorator:

public class TailTankDecorator extends TankDecorator {}

BloodTankDecorator:

public class BloodTankDecorator extends TankDecorator{}

Client:

public class Client {
    public static void main(String[] args) {
        // 最初的坦克
        Tank tank = new BaseTank();
        // 给我们的坦克增加一个血条
        tank = new BloodTankDecorator(tank);
        // 给我们的坦克增加一个尾巴
        tank = new TailTankDecorator(tank);
        // 给我们的坦克增加一个攻击
        tank = new AttackTankDecorator(tank);
        // 输出坦克当前含有的功能
        tank.operation();
//        我拥有攻击的功能 
//        我拥有尾巴的功能
//        我拥有血条的功能
//        我拥有移动的功能
    }
}

四、总结

当我们想要对一个类增加一些功能或者动态的对一个类增加功能时,最朴素的方法是在原有的类中加入功能,但这种方法会导致原有的类过于膨胀,代码过于臃肿,不便维护。

反观装饰者模式,装饰类和被装饰类可以独立发展,而不会互相耦合,它有效的把对象的职责和装饰功能给区分开。

当然,装饰者模式也有弊端,通过代码我们可以看到,在我们进行修饰的时候,是一层一层进行修饰,假如最里面的修饰过程出现问题,那么修改的工作量可想而知。



相关文章
|
4月前
|
设计模式 存储 缓存
【设计模式】【结构型模式】享元模式(Flyweight)
一、入门 什么是享元模式? 享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用,特别适用于存在大量相似对象的情况。 它的核心思想是将对象的内在状态(不变
166 16
|
4月前
|
设计模式 Java 数据库连接
【设计模式】【结构型模式】代理模式(Proxy)
一、入门 什么是代理模式? 代理模式(Proxy Pattern)是一种结构型设计模式,允许你提供一个代理对象来控制对另一个对象的访问。 代理对象在客户端和目标对象之间起到中介作用,可以在不改变目标对
101 10
|
4月前
|
设计模式 Java 定位技术
【设计模式】【结构型模式】组合模式(Composite)
一、入门 什么是组合模式 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式使得客户端可以统一处理单个对象和组合对
127 10
|
4月前
|
关系型数据库 Java MySQL
【设计模式】【结构型模式】桥接模式(Bridge)
一、入门 什么是桥接模式? 桥接模式(Bridge Pattern)是一种结构型设计模式,核心思想是将抽象与实现分离,让它们可以独立变化。简单来说,它像一座“桥”连接了两个维度的变化,避免用继承导致代
263 10
|
4月前
|
设计模式 前端开发 Java
【设计模式】【结构型模式】适配器模式(Adpter)
一、入门 什么是适配器模式? 适配器模式是Java中常用的结构型设计模式,它的核心作用就像现实中的电源转换器一样---让原本不兼容的两个接口能够协同工作。 为什么要用适配器模式? 假设我们需要在电商系
108 10
|
4月前
|
设计模式 Java 数据库连接
【设计模式】【结构型模式】外观模式(Facde)
一、入门 什么是外观模式? 一种结构型设计模式,通过为子系统中的一组接口提供一个统一的高层接口(称为外观),来简化客户端与复杂子系统的交互过程。其本质是建立抽象层来隔离复杂度。 为什么要有外观模式?
175 9
|
4月前
|
设计模式 缓存 安全
【设计模式】【结构型模式】装饰者模式(Decorator)
一、入门 什么是装饰者模式? 装饰者模式(Decorator Pattern)是 Java 中常用的结构型设计模式,它能在不修改原有对象结构的前提下,动态地为对象添加额外的职责。 为什么要装饰者模式?
82 8
|
6月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
|
8月前
|
设计模式 存储
「全网最细 + 实战源码案例」设计模式——装饰者模式
装饰者模式(Decorator Pattern)是一种结构型设计模式,通过“包装”现有对象来为其添加额外功能,而无需修改原有代码。它通过创建装饰类来扩展对象的功能,而非继承。该模式由抽象构件、具体构件、抽象装饰者和具体装饰者组成,允许在运行时动态组合功能。穿衣服的例子很好地解释了装饰者模式:你可以根据需要一层层添加衣物,如毛衣、夹克和雨衣,每件衣物都扩展了基本行为,但不是你的一部分,可以随时脱掉。 优点包括灵活性、避免子类爆炸和符合开闭原则;缺点是可能增加复杂性和难以理解。适用于希望在不修改代码的情况下为对象新增行为的场景,尤其当继承难以实现或不可行时。
129 15
|
9月前
|
设计模式 Java Kotlin
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
103 2