设计模式之装饰器模式

一、介绍

装饰器模式(Decoration Pattern),属于结构型设计模式 ,用于在不改变现有对象 的基础上,对该对象的方法动态 地添加新的功能,实现对该对象原有方法的增强

装饰器模式的设计思想是将对象的核心功能附加功能独立开来。核心功能由现有对象提供,附加功能由装饰器提供。

装饰器的实现思路是存在一个抽象的装饰器类 ,该装饰器类用于对现有的对象进行包装,然后通过该装饰器的具体子类对包装的类的方法进行增强。推而论之,在存在多个装饰器具体子类的情况下,可以动态地对现有对象随心所欲进行嵌套包装,对现有对象进行包装后,可以在已包装基础上进行多层嵌套包装

二、主要角色

在装饰器模式中,主要包含以下四个角色:

  • 核心组件抽象接口(Component)

规定了被装饰对象的行为。

  • 核心组件具体实现(ComponentImpl)

实现核心组件抽象接口,对接口规定的行为进行具体实现。

  • 抽象装饰器(AbsDecoration)

通用的装饰ComponentImpl的装饰器,该装饰器必须包含一个以被装饰对象为参数的构造方法。

该装饰器设定为抽象类的原因是通过其构造函数管理被装饰的对象,以此来限制具体装饰器的构造方法必须传入被装饰的对象。

  • 具体装饰器(Decoration)

继承抽象装饰器。用于增强对被装饰对象某一功能的特定装饰逻辑

三、案例

核心组件抽象接口

复制代码
public interface Coffee {
    /**
     * 获取描述信息
     */
    String getDescription();

    /**
     * 获取花费
     */
    double getCost();
}

核心组件具体实现

黑咖啡 就是核心

java 复制代码
public class BlackCoffee implements Coffee{
    @Override
    public String getDescription() {
        return "黑咖啡";
    }

    @Override
    public double getCost() {
        return 10;
    }
}

抽象装饰器

java 复制代码
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
    @Override
    public String getDescription() {
        return coffee.getDescription();
    }

    @Override
    public double getCost() {
        return coffee.getCost();
    }
}

具体装饰器

给咖啡加牛奶

java 复制代码
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription()+ " 加奶";
    }

    @Override
    public double getCost() {
        return super.getCost()+ 5 ;
    }

}

给咖啡加糖

java 复制代码
public class SugarDecorator extends CoffeeDecorator{
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", 加糖";
    }

    @Override
    public double getCost() {
        return super.getCost() + 2;
    }
}

测试

在存在多个装饰器具体子类的情况下,可以动态地对现有对象随心所欲进行嵌套包装

上面的例子也可以加2分牛牛奶一份糖,可以随心所欲的进行装饰。

四、装饰器模式在jdk的应用

java中的IO是明显的装饰器模式的运用。FilterInputStream,FilterOutputStream,FilterRead,FilterWriter分别为具体装饰器的父类,相当于Decorator类,它们分别实现了InputStream,OutputStream,Reader,Writer类(这些类相当于Component,是其他组件类的父类,也是Decorator类的父类)。

继承自InputStream,OutputStream,Reader,Writer这四个类的其他类是具体的组件类,每个都有相应的功能,相当于ConcreteComponent类。而继承自FilterInputStream,FilterOutputStream,FilterRead,FilterWriter这四个类的其他类就是具体的装饰器对象类,即ConcreteDecorator类。通过这些装饰器类,可以给我们提供更加具体的有用的功能。如FileInputStream是InputStream的一个子类,从文件中读取数据流,BufferedInputStream是继承自FilterInputStream的具体的装饰器类,该类提供一个内存的缓冲区类保存输入流中的数据。我们使用如下的代码来使用BufferedInputStream装饰FileInputStream,就可以提供一个内存缓冲区来保存从文件中读取的输入流

①组件接口,相当于Component:

InputStream

OutputStream

Reader

Writer

②组件的实现类,相当于ConcreteComponent

FileInputStream

③装饰器接口,相当于Decorator

FilterInputStream

FilterOutputStream

FilterRead

FilterWriter

④装饰器类

BufferedInputStream继承自FilterInputStream

使用说明:我们可以用BufferedInputStream修饰FileInputStream

例如

java 复制代码
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 
//其中file为某个具体文件的File或者FileDescription对象
java 复制代码
FileWriter file = new FileWriter("sample.txt");
BufferedWriter writer = new BufferedWriter(file);
writer.write("a small amount of sample text");
writer.newLine();
writer.close();

五、优缺点

优点

由于装饰器对象和被装饰的对象都实现于核心抽象接口,根据面向接口编程原则,它们具有相同的行为。

装饰器不仅可以将已有对象进行包装,也可以对装饰器对象嵌套包装。

通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。

避免多个被装饰对象与装饰器而导致最终类数量上的膨胀。
缺点

每当为被装饰对象添加新的功能,都需要为其新建一个装饰类

六、适用场景

动态功能扩展: 运行时为对象添加或移除功能(如日志、缓存、加密)
避免多层继承: 替代复杂的继承树(如 BufferedFileReader、EncryptedFileReader)
透明性要求: 客户端无需感知对象是否被装饰(保持接口一致性)。
功能组合复用: 支持多种功能的自由组合(如 压缩 + 加密 文件流)

相关推荐
荒诞硬汉1 分钟前
面向对象(三)
java·开发语言
柒.梧.5 分钟前
Spring Boot集成JWT Token实现认证授权完整实践
java·spring boot·后端
白露与泡影5 分钟前
放弃 IntelliJ IDEA,转 VS Code 了。。
java·ide·intellij-idea
迷雾骑士7 分钟前
IDEA中将项目提交到Gitee仓库
java·gitee·intellij-idea
菜鸟233号9 分钟前
力扣416 分割等和子串 java实现
java·数据结构·算法·leetcode
奔波霸的伶俐虫12 分钟前
redisTemplate.opsForList()里面方法怎么用
java·开发语言·数据库·python·sql
自在极意功。14 分钟前
简单介绍SpringAOP
java·spring·aop思想
__万波__15 分钟前
二十三种设计模式(二十三)--责任链模式
java·设计模式·责任链模式
TT哇16 分钟前
基础的IDEA基本使用,如:debug流程、常用快捷键
java·ide·intellij-idea
梵得儿SHI18 分钟前
(第七篇)Spring AI 核心技术攻坚:国内模型深度集成与国产化 AI 应用实战指南
java·人工智能·spring·springai框架·国产化it生态·主流大模型的集成方案·麒麟系统部署调优