Java 设计模式:装饰者模式(Decorator Pattern)
一、模式定义
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
二、核心角色
- Component(组件接口) - 定义被装饰对象的公共接口
 
- ConcreteComponent(具体组件) - 实现基础功能的具体类
 
- Decorator(装饰者基类) - 持有Component引用,实现Component接口
 
- ConcreteDecorator(具体装饰者) - 添加具体装饰功能的实现类
 
三、经典实现(咖啡店订单系统)
// 1. 组件接口
public interface Coffee {
    String getDescription();
    double cost();
}
// 2. 具体组件
public class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }
    @Override
    public double cost() {
        return 1.0;
    }
}
// 3. 装饰者基类
public abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decoratedCoffee;
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
    @Override
    public double cost() {
        return decoratedCoffee.cost();
    }
}
// 4. 具体装饰者
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    @Override
    public String getDescription() {
        return super.getDescription() + ", Milk";
    }
    @Override
    public double cost() {
        return super.cost() + 0.5;
    }
}
public class MochaDecorator extends CoffeeDecorator {
    public MochaDecorator(Coffee coffee) {
        super(coffee);
    }
    @Override
    public String getDescription() {
        return super.getDescription() + ", Mocha";
    }
    @Override
    public double cost() {
        return super.cost() + 0.7;
    }
}
// 5. 客户端使用
public class CoffeeShop {
    public static void main(String[] args) {
        Coffee order = new SimpleCoffee();
        System.out.println(order.getDescription() + " $" + order.cost());
        order = new MilkDecorator(order);
        System.out.println(order.getDescription() + " $" + order.cost());
        order = new MochaDecorator(order);
        System.out.println(order.getDescription() + " $" + order.cost());
    }
}
四、模式结构UML
           _________________________
          |        Component        |
          |-------------------------|
          | + getDescription()      |
          | + cost()                |
          |_________________________|
                     ▲
          ___________|___________
         |                       |
 _________▼_________       ______▼_______
| ConcreteComponent |     |   Decorator  |
|-------------------|     |--------------|
| + getDescription()|     | - component  |
| + cost()          |     |______________|
|___________________|              ▲
                           _________|_________
                          |                   |
                   _______▼_______     _______▼_______
                  | ConcreteDecoratorA |   | ConcreteDecoratorB |
                  |--------------------|   |--------------------|
                  | + addedBehavior()  |   | + addedBehavior()  |
                  |____________________|   |____________________|
五、模式优劣分析
优势:
- 动态扩展功能,比继承更灵活
- 符合开闭原则,无需修改现有代码
- 支持多层嵌套装饰
- 不同装饰类可自由组合
劣势:
- 多层装饰增加代码复杂度
- 装饰顺序影响最终结果
- 可能产生大量小类
- 调试困难(需逐层检查装饰)
六、应用场景
- 动态扩展对象功能
 (如为图形界面组件添加边框、滚动条)
- 撤销功能实现
 (通过装饰记录操作历史)
- 数据流处理
 (Java I/O中的缓冲、加密处理)
- 权限控制
 (通过装饰添加权限校验层)
- 日志记录
 (为业务逻辑添加日志装饰)
七、Java标准库应用
Java I/O流典型实现:
// 多层装饰示例
InputStream in = new FileInputStream("data.txt");
in = new BufferedInputStream(in);      // 添加缓冲功能
in = new GZIPInputStream(in);          // 添加解压缩功能
in = new Base64InputStream(in);        // 添加Base64解码
// 自定义装饰者示例
class UppercaseInputStream extends FilterInputStream {
    public UppercaseInputStream(InputStream in) {
        super(in);
    }
    @Override
    public int read() throws IOException {
        int c = super.read();
        return (c == -1) ? c : Character.toUpperCase(c);
    }
}
八、高级应用技巧
透明性控制
通过接口继承保持装饰透明性:
interface Window {
    void draw();
}
class BasicWindow implements Window { /*...*/ }
abstract class WindowDecorator implements Window {
    protected Window window;
    // 不暴露额外方法
}
装饰顺序控制
使用建造者模式管理装饰顺序:
public class CoffeeBuilder {
    private Coffee coffee = new SimpleCoffee();
    public CoffeeBuilder addMilk() {
        coffee = new MilkDecorator(coffee);
        return this;
    }
    public Coffee build() {
        return coffee;
    }
}
动态移除装饰
实现装饰栈管理:
public class UndoableCoffee implements Coffee {
    private Deque<Coffee> stack = new ArrayDeque<>();
    public UndoableCoffee(Coffee coffee) {
        stack.push(coffee);
    }
    public void addDecorator(CoffeeDecorator decorator) {
        stack.push(decorator);
    }
    public void undo() {
        if (stack.size() > 1) {
            stack.pop();
        }
    }
    // 实现Coffee接口方法...
}
九、最佳实践建议
- 保持组件接口简洁
 避免装饰者需要实现过多无关方法
- 控制装饰层次深度
 建议不超过4层装饰
- 优先使用透明装饰
 保持装饰前后接口一致
- 注意线程安全问题
 对于可变状态装饰器,使用同步控制
- 性能敏感场景慎用
 多层装饰可能影响性能(建议结合对象池)
Java 设计模式:装饰者模式(Decorator Pattern)的更多相关文章
- 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法
		装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ... 
- 浅谈设计模式--装饰者模式(Decorator Pattern)
		挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ... 
- 设计模式 - 装饰者模式(Decorator Pattern) 具体解释
		装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ... 
- Java设计模式——装饰器模式(Decorator)
		今天上课讲了java设计模式中的装饰器模式--Decorator,由于早上起的很早,肚子也很饿,知识点本身也晦涩难懂,听的云里雾里的,所以在课下对这块的知识做出一些总结. 定义 装饰器模式又名包装(W ... 
- C#设计模式——装饰者模式(Decorator Pattern)
		一.例子在软件开发中,我们往往会想要给某一类对象增加不同的功能.比如要给汽车增加ESP.天窗或者定速巡航.如果利用继承来实现,就需要定义无数的类,Car,ESPCar,CCSCar,SunRoofCa ... 
- 设计模式学习--装饰者模式(Decorator Pattern)
		概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ... 
- JAVA设计模式--装饰器模式
		装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ... 
- Java设计模式——装饰者模式
		JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ... 
- 【设计模式】Java设计模式 - 装饰者模式
		Java设计模式 - 装饰者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自 ... 
- 从源码角度理解Java设计模式——装饰者模式
		一.饰器者模式介绍 装饰者模式定义:在不改变原有对象的基础上附加功能,相比生成子类更灵活. 适用场景:动态的给一个对象添加或者撤销功能. 优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个 ... 
随机推荐
- 谈谈 HTTP/2 的协议协商机制
			在过去的几个月里,我写了很多有关 HTTP/2 的文章,也做过好几场相关分享.我在向大家介绍 HTTP/2 的过程中,有一些问题经常会被问到.例如要部署 HTTP/2 一定要先升级到 HTTPS 么? ... 
- Qt/C++地图动态绘制折线多边形矩形圆形标注点/可编辑拖动调整大小和位置
			一.前言说明 无论哪一家的地图,都提供了调用函数绘制各种覆盖物,但是有时候的场景是希望进入添加覆盖物模式,然后每次在地图上按下都自动生成对应的覆盖物比如圆形,这样就不需要用户提前知道经纬度坐标等参数, ... 
- 【狂神说Java】Java零基础学习笔记-Java流程控制
			[狂神说Java]Java零基础学习笔记-Java流程控制 Scanner对象 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入.ja ... 
- python SQLAlchemy ORM——从零开始学习 01 安装库
			01基础库 1-1安装 依赖库:sqlalchemy pip install sqlalchemy #直接安装即可 1-2导入使用 这里讲解思路[个人的理解],具体写其实就是这个框架: 导入必要的接口 ... 
- CDS标准视图:测量点数据 I_MeasuringPointData
			视图名称:测量点数据 I_MeasuringPointData 视图类型:基础视图 视图代码: 点击查看代码 @AbapCatalog.sqlViewName: 'IMEASPOINTDATA' @A ... 
- Superset 用户集成方案
			注意,一下内容来自外网浏览器翻译,本人使用了将superset集成进入第三方系统,superset采用自定义身份验证+第三系统iframe嵌入方式,但是这个方式存在一个问题,iframe与redire ... 
- 小程序uni-app处理input框将页面往上推动的解决办法
			1. view <view class="bottom-wri-box" :style="{bottom: bottomHeight}"> < ... 
- Java02-基础语法
			Java基础语法 [ 任务列表 ] 1.注释 2.字面量 3.变量 4.关键字.标识符 5.方法 6.类型转换 7.输入输出 8.运算符 9.其他 -------------------------- ... 
- Windows的MySQL数据库升级(解压包方式)
			1.背景描述 原来的 MySQL 在安装时,是最新的稳定版本 5.7.33 . 经过一段时间后,在原来的 MySQL 版本中,发现存在漏洞. 因为 MySQL 的官方补丁,需要 Oracle 的 si ... 
- Flink同步kafka到iceberg(cos存储)
			一.flink到logger 1.source create table source_table ( id bigint comment '唯一编号' ,order_number bigint co ... 
