10.设计模式-DECORATOR(装饰)

一、模式定义与核心思想

装饰器模式是一种结构型设计模式,其核心目标是通过动态包装对象的方式,在不修改原有类代码的前提下,灵活扩展对象的功能。该模式以“组合优于继承”为设计哲学,通过多层嵌套装饰器实现功能的按需叠加,完美解决以下问题:

  1. 动态扩展:运行时按需添加或移除功能(如为文本动态叠加加密、压缩等处理层)
  2. 避免继承爆炸:当存在多种功能组合时,无需为每个组合创建子类(如咖啡加料的N种组合场景)
  3. 职责解耦:将核心功能与附加功能分离(如日志记录、权限校验等横切关注点)

核心价值

  • 开闭原则:扩展开放,修改关闭
  • 功能热插拔:支持运行时动态调整功能组合
  • 复用性提升:每个装饰器仅关注单一功能增强

二、模式组成与UML类图

核心角色
  1. Component(抽象组件)
    • 定义统一接口(如Coffee接口的getCost()getDescription()
  1. ConcreteComponent(具体组件)
    • 实现基础功能(如SimpleCoffee提供基础咖啡)
  1. Decorator(抽象装饰器)
    • 持有组件引用,定义装饰逻辑(如CoffeeDecorator基类)
  1. ConcreteDecorator(具体装饰器)
    • 实现具体扩展功能(如MilkDecorator添加牛奶)
UML类图
classDiagram
    class Component {
        <<interface>>
        +operation()
    }

    class ConcreteComponent {
        +operation()
    }

    class Decorator {
        -component: Component
        +operation()
    }

    class ConcreteDecoratorA {
        +operation()
        +addedBehavior()
    }

    class ConcreteDecoratorB {
        +operation()
        +addedBehavior()
    }

    Component <|-- ConcreteComponent
    Component <|-- Decorator
    Decorator <|-- ConcreteDecoratorA
    Decorator <|-- ConcreteDecoratorB
    Decorator o-- Component


三、代码实现示例

场景:实现可定制化的咖啡加料系统
// 1. 抽象组件
interface Coffee {
    double getCost();
    String getDescription();
}

// 2. 具体组件
class SimpleCoffee implements Coffee {
    public double getCost() { return 2.0; }
    public String getDescription() { return "基础咖啡"; }
}

// 3. 抽象装饰器
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
}

// 4. 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) { super(coffee); }

    public double getCost() {
        return super.decoratedCoffee.getCost() + 0.5;
    }

    public String getDescription() {
        return super.decoratedCoffee.getDescription() + ", 加牛奶";
    }
}

class CaramelDecorator extends CoffeeDecorator {
    public CaramelDecorator(Coffee coffee) { super(coffee); }

    public double getCost() {
        return super.decoratedCoffee.getCost() + 1.0;
    }

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

// 5. 客户端调用
public class Client {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        coffee = new MilkDecorator(coffee);
        coffee = new CaramelDecorator(coffee);

        System.out.println(coffee.getDescription()); 
        // 输出:基础咖啡, 加牛奶, 加焦糖
        System.out.println(coffee.getCost()); 
        // 输出:3.5
    }
}

四、工业级源码应用

  1. Java I/O流体系(经典案例)
InputStream in = new BufferedInputStream(  // 缓冲装饰器[10,11](@ref)
    new GZIPInputStream(        // 解压装饰器
        new FileInputStream("data.gz"))); // 基础组件
  • 设计解析FileInputStream作为具体组件,BufferedInputStreamGZIPInputStream作为装饰器,按需叠加功能
  1. Spring框架缓存管理
@Cacheable(value="users", 
           cacheManager="compositeCacheManager") // 组合多个缓存装饰器
public User getUser(Long id) {...}
  • 通过CompositeCacheManager整合Redis、Ehcache等不同缓存实现
  1. Android UI组件系统
View view = new ScrollViewDecorator(  // 滚动条装饰器
    new BorderDecorator(       // 边框装饰器
        new TextView()));          // 基础组件
  • 动态为UI控件添加滚动、阴影等视觉特效
  1. 游戏角色装备系统
Character warrior = new ArmorDecorator(    // 护甲装饰器
    new WeaponDecorator(    // 武器装饰器
        new BaseCharacter()));  // 基础角色
  • 动态叠加攻击力、防御力等属性加成
  1. MyBatis二级缓存
<cache type="org.mybatis.caches.redis.RedisCache">
<property name="eviction" value="LRU"/>
</cache>
  • 通过FifoCacheLruCache等装饰器扩展缓存策略

总结

装饰器模式如同软件世界的“俄罗斯套娃”,通过层层嵌套的包装机制,为系统功能的动态扩展提供了优雅的解决方案。其核心价值在Java I/O流体系、Spring框架等工业级系统中得到充分验证,成为应对需求变化的利器。掌握该模式的关键在于准确识别功能扩展维度,并通过合理的接口设计实现功能的热插拔组合

posted @ 2025-04-12 10:44  雾里看花的少年  阅读(45)  评论(0)    收藏  举报