Java设计模式——装饰器模式

⚪装饰器模式(Decorator)是一种结构型设计模式,这种模式允许类在不改变其接口的情况下增加行为。

⚪意图:允许动态地将责任附加到对象上。

⚪以下是工厂方法模式的关键要点:

        ▷ 角色和责任

  1. Component(组件):定义一个抽象接口或抽象类,具有需要被装饰的方法。
  2. ConcreteComponent(具体组件):实现 Component 接口,是被装饰的具体对象。
  3. Decorator(装饰器抽象类):也是实现 Component 接口的抽象类,它包含一个对 Component 对象的引用,以及与 Component 接口一致的方法,通常这些方法会调用被装饰对象的方法。
  4. ConcreteDecorator(具体装饰器):实现了 Decorator 类,可以附加额外的职责到 Component 对象上。

        ▷ 工作流程

  1. 创建一个抽象的组件接口(Component),定义需要被装饰的方法。
  2. 创建具体的组件类(ConcreteComponent),实现组件接口。
  3. 创建一个抽象的装饰器类(Decorator),它也实现组件接口,但包含了一个对组件的引用。
  4. 创建具体的装饰器类(ConcreteDecorator),继承自装饰器抽象类,实现装饰器接口,可以在其中附加额外的职责。
  5. 在客户端代码中,首先创建一个具体组件对象,然后可以创建一个或多个具体装饰器对象,用于装饰组件。

        ▷ 示例

// 1. 创建组件接口
interface Coffee {
    double cost();
}

// 2. 创建具体组件类
class SimpleCoffee implements Coffee {
    @Override
    public double cost() {
        return 2.0; // 基本咖啡的价格
    }
}

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

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

    @Override
    public double cost() {
        return decoratedCoffee.cost();
    }
}

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

    @Override
    public double cost() {
        return super.cost() + 1.0; // 牛奶的价格
    }
}

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

    @Override
    public double cost() {
        return super.cost() + 0.5; // 糖的价格
    }
}

public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 创建基本咖啡
        Coffee coffee = new SimpleCoffee();
        System.out.println("Cost of simple coffee: " + coffee.cost());

        // 添加牛奶
        coffee = new MilkDecorator(coffee);
        System.out.println("Cost of coffee with milk: " + coffee.cost());

        // 再添加糖
        coffee = new SugarDecorator(coffee);
        System.out.println("Cost of coffee with milk and sugar: " + coffee.cost());
    }
}

⚪适用性

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  2. 处理那些可以撤销的职责。
  3. 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产牛大量的子类,使得子类数目早爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。

⚪应用场景

  1. 动态扩展对象的功能:当你需要在不修改现有对象代码的情况下,增加对象的功能时,装饰器模式非常有用。它允许你通过添加装饰器类来动态地包装一个对象,以添加额外的行为。
  2. 多层次的组合:如果需要多个不同的装饰器类进行组合,以达到各种不同的组合效果,装饰器模式是一个非常灵活的方式来实现这种多层次的组合。
  3. 避免子类爆炸:当存在大量可能组合的方式时,使用子类来表示每种组合会导致类的爆炸性增长。装饰器模式可以避免创建大量的子类。

⚪实际已有场景

  1. Java I/O 类库:Java 的输入输出类库中大量使用了装饰器模式。例如,BufferedReader 和 BufferedWriter 用于缓冲输入和输出流,InputStreamReader 和 OutputStreamWriter 用于字符流与字节流之间的转换,这些都是装饰器的典型应用。
  2. Java Swing GUI 库:Swing 中的组件也使用了装饰器模式。例如,JScrollPane 用于添加滚动功能,JPanel 用于添加边框和背景等。你可以动态地添加和删除这些装饰器,以改变 GUI 组件的外观和行为。
  3. Spring AOP(面向切面编程):Spring 框架中的 AOP 部分使用了装饰器模式的思想。在 AOP 中,您可以创建切面(Aspect)并使用装饰器模式来动态地将切面织入到应用程序的不同组件中,以添加横切关注点,如日志、事务管理等。
  4. Spring Security:Spring Security 是 Spring 家族中用于处理认证和授权的框架。它使用了装饰器模式来实现安全性功能。例如,您可以使用装饰器来配置身份验证和授权规则,并将它们应用于不同的 URL 或方法。

 

posted @ 2023-10-04 10:20  xiaogh  阅读(136)  评论(0)    收藏  举报