Java装饰器模式详解

装饰器模式详解

一、装饰器模式概述

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

核心特点

  • 动态扩展:运行时添加或撤销功能
  • 透明装饰:装饰后的对象与原始对象接口一致
  • 替代继承:通过组合而非继承扩展功能
  • 灵活组合:可以嵌套多个装饰器

二、装饰器模式的结构

主要角色

  1. Component:抽象组件,定义被装饰对象的接口
  2. ConcreteComponent:具体组件,实现抽象组件接口
  3. Decorator:抽象装饰器,继承/实现Component并持有Component引用
  4. ConcreteDecorator:具体装饰器,实现附加功能

三、装饰器模式的实现

1. 基本实现

// 抽象组件
public interface Coffee {
    double getCost();
    String getDescription();
}

// 具体组件
public class SimpleCoffee implements Coffee {
    public double getCost() {
        return 1.0;
    }
    
    public String getDescription() {
        return "普通咖啡";
    }
}

// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decoratedCoffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
    
    public double getCost() {
        return decoratedCoffee.getCost();
    }
    
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}

// 具体装饰器 - 牛奶
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double getCost() {
        return super.getCost() + 0.5;
    }
    
    public String getDescription() {
        return super.getDescription() + ", 加牛奶";
    }
}

// 具体装饰器 - 糖
public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double getCost() {
        return super.getCost() + 0.2;
    }
    
    public String getDescription() {
        return super.getDescription() + ", 加糖";
    }
}

// 使用示例
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);

System.out.println("费用: " + coffee.getCost());
System.out.println("描述: " + coffee.getDescription());

2. IO流中的装饰器模式

// 模拟InputStream
public abstract class InputStream {
    public abstract int read();
    public abstract void close();
}

// 模拟FileInputStream
public class FileInputStream extends InputStream {
    public int read() {
        System.out.println("读取文件数据");
        return 0;
    }
    
    public void close() {
        System.out.println("关闭文件流");
    }
}

// 模拟BufferedInputStream
public class BufferedInputStream extends InputStream {
    private InputStream in;
    
    public BufferedInputStream(InputStream in) {
        this.in = in;
    }
    
    public int read() {
        System.out.println("缓冲读取");
        return in.read();
    }
    
    public void close() {
        in.close();
    }
}

四、装饰器模式的应用场景

1. Java I/O流体系

// 实际Java IO示例
InputStream in = new FileInputStream("data.txt");
in = new BufferedInputStream(in);
in = new DataInputStream(in);

2. Web请求处理

// HTTP请求处理器接口
public interface HttpRequestHandler {
    void handle(HttpRequest request);
}

// 基础处理器
public class BasicHandler implements HttpRequestHandler {
    public void handle(HttpRequest request) {
        System.out.println("处理基本请求");
    }
}

// 认证装饰器
public class AuthenticationDecorator implements HttpRequestHandler {
    private HttpRequestHandler handler;
    
    public AuthenticationDecorator(HttpRequestHandler handler) {
        this.handler = handler;
    }
    
    public void handle(HttpRequest request) {
        if (authenticate(request)) {
            handler.handle(request);
        } else {
            throw new SecurityException("认证失败");
        }
    }
    
    private boolean authenticate(HttpRequest request) {
        // 认证逻辑
        return true;
    }
}

// 日志装饰器
public class LoggingDecorator implements HttpRequestHandler {
    private HttpRequestHandler handler;
    
    public LoggingDecorator(HttpRequestHandler handler) {
        this.handler = handler;
    }
    
    public void handle(HttpRequest request) {
        System.out.println("开始处理请求: " + request.getUrl());
        handler.handle(request);
        System.out.println("请求处理完成");
    }
}

3. 图形界面组件

// GUI组件接口
public interface VisualComponent {
    void draw();
    void resize();
}

// 基础文本框
public class TextView implements VisualComponent {
    public void draw() {
        System.out.println("绘制文本框");
    }
    
    public void resize() {
        System.out.println("调整文本框大小");
    }
}

// 边框装饰器
public class BorderDecorator implements VisualComponent {
    private VisualComponent component;
    private int borderWidth;
    
    public BorderDecorator(VisualComponent component, int width) {
        this.component = component;
        this.borderWidth = width;
    }
    
    public void draw() {
        component.draw();
        drawBorder();
    }
    
    public void resize() {
        component.resize();
    }
    
    private void drawBorder() {
        System.out.println("绘制边框,宽度: " + borderWidth);
    }
}

五、装饰器模式的变体

1. 透明装饰器模式

// 透明装饰器接口
public interface TransparentDecorator extends VisualComponent {
    void addedBehavior();
}

// 具体透明装饰器
public class ScrollDecorator implements TransparentDecorator {
    private VisualComponent component;
    
    public ScrollDecorator(VisualComponent component) {
        this.component = component;
    }
    
    public void draw() {
        component.draw();
        drawScroll();
    }
    
    public void resize() {
        component.resize();
    }
    
    public void addedBehavior() {
        System.out.println("滚动行为");
    }
    
    private void drawScroll() {
        System.out.println("绘制滚动条");
    }
}

2. 半透明装饰器模式

// 扩展接口
public interface Scrollable {
    void scrollTo(int position);
}

// 半透明装饰器
public class ScrollDecorator implements VisualComponent, Scrollable {
    private VisualComponent component;
    
    public ScrollDecorator(VisualComponent component) {
        this.component = component;
    }
    
    public void draw() {
        component.draw();
        drawScroll();
    }
    
    public void resize() {
        component.resize();
    }
    
    public void scrollTo(int position) {
        System.out.println("滚动到位置: " + position);
    }
    
    private void drawScroll() {
        System.out.println("绘制滚动条");
    }
}

六、装饰器模式的优缺点

优点

  1. 灵活扩展:比继承更灵活的功能扩展方式
  2. 避免子类膨胀:通过组合实现功能叠加
  3. 动态添加功能:运行时添加或移除装饰
  4. 单一职责原则:每个装饰类只关注一个功能

缺点

  1. 复杂度增加:多层装饰可能使代码难以理解
  2. 小对象多:会产生许多小装饰器对象
  3. 初始化复杂:创建高度装饰的对象需要多步操作

七、最佳实践

  1. 合理设计组件接口:保持装饰器和组件接口一致
  2. 控制装饰层数:避免过度装饰导致复杂度过高
  3. 文档化装饰顺序:某些装饰器可能有顺序依赖
  4. 考虑性能影响:多层装饰可能带来性能开销
  5. 与工厂模式结合:简化装饰对象的创建过程

八、总结

装饰器模式是动态扩展对象功能的强大工具,特别适用于:

  • 需要动态/透明地添加或撤销功能
  • 不适合使用子类扩展的情况
  • 需要组合多个独立扩展功能
  • 系统需要运行时添加功能

在实际开发中,装饰器模式常见于:

  • Java I/O流体系
  • Web中间件开发
  • GUI组件装饰
  • 权限控制/日志记录等横切关注点

正确使用装饰器模式可以提高系统的灵活性和可扩展性,但需要注意不要过度使用,以免增加系统复杂性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值