前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Java 设计模式:装饰者模式(Decorator Pattern)

Java 设计模式:装饰者模式(Decorator Pattern)

原创
作者头像
用户11531739
发布2025-03-14 15:27:26
发布2025-03-14 15:27:26
270
举报
一、模式定义

装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。

二、核心角色
  1. Component(组件接口)
    • 定义被装饰对象的公共接口
  2. ConcreteComponent(具体组件)
    • 实现基础功能的具体类
  3. Decorator(装饰者基类)
    • 持有Component引用,实现Component接口
  4. ConcreteDecorator(具体装饰者)
    • 添加具体装饰功能的实现类
三、经典实现(咖啡店订单系统)
代码语言:java
复制
// 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
代码语言:java
复制
           _________________________
          |        Component        |
          |-------------------------|
          | + getDescription()      |
          | + cost()                |
          |_________________________|
                     ▲
          ___________|___________
         |                       |
 _________▼_________       ______▼_______
| ConcreteComponent |     |   Decorator  |
|-------------------|     |--------------|
| + getDescription()|     | - component  |
| + cost()          |     |______________|
|___________________|              ▲
                           _________|_________
                          |                   |
                   _______▼_______     _______▼_______
                  | ConcreteDecoratorA |   | ConcreteDecoratorB |
                  |--------------------|   |--------------------|
                  | + addedBehavior()  |   | + addedBehavior()  |
                  |____________________|   |____________________|
五、模式优劣分析

优势:

  • 动态扩展功能,比继承更灵活
  • 符合开闭原则,无需修改现有代码
  • 支持多层嵌套装饰
  • 不同装饰类可自由组合

劣势:

  • 多层装饰增加代码复杂度
  • 装饰顺序影响最终结果
  • 可能产生大量小类
  • 调试困难(需逐层检查装饰)
六、应用场景
  1. 动态扩展对象功能undefined(如为图形界面组件添加边框、滚动条)
  2. 撤销功能实现undefined(通过装饰记录操作历史)
  3. 数据流处理undefined(Java I/O中的缓冲、加密处理)
  4. 权限控制undefined(通过装饰添加权限校验层)
  5. 日志记录undefined(为业务逻辑添加日志装饰)
七、Java标准库应用

Java I/O流典型实现:

代码语言:java
复制
// 多层装饰示例
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);
    }
}
八、高级应用技巧

透明性控制

通过接口继承保持装饰透明性:

代码语言:java
复制
interface Window {
    void draw();
}

class BasicWindow implements Window { /*...*/ }

abstract class WindowDecorator implements Window {
    protected Window window;
    // 不暴露额外方法
}

装饰顺序控制

使用建造者模式管理装饰顺序:

代码语言:java
复制
public class CoffeeBuilder {
    private Coffee coffee = new SimpleCoffee();
    
    public CoffeeBuilder addMilk() {
        coffee = new MilkDecorator(coffee);
        return this;
    }
    
    public Coffee build() {
        return coffee;
    }
}

动态移除装饰

实现装饰栈管理:

代码语言:java
复制
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接口方法...
}
九、最佳实践建议
  1. 保持组件接口简洁undefined避免装饰者需要实现过多无关方法
  2. 控制装饰层次深度undefined建议不超过4层装饰
  3. 优先使用透明装饰undefined保持装饰前后接口一致
  4. 注意线程安全问题undefined对于可变状态装饰器,使用同步控制
  5. 性能敏感场景慎用undefined多层装饰可能影响性能(建议结合对象池)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、模式定义
  • 二、核心角色
  • 三、经典实现(咖啡店订单系统)
  • 四、模式结构UML
  • 五、模式优劣分析
  • 六、应用场景
  • 七、Java标准库应用
  • 八、高级应用技巧
  • 九、最佳实践建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档