结构型模式-2.装饰器模式(Decorator Pattern)

 2024-07-29    0 条评论    66 浏览

设计模式

装饰器模式是一种结构型设计模式,它允许你动态地给一个对象添加额外的功能,而无需修改它的代码。这种模式通过创建一个包装对象来实现,也就是说,实际的对象可以被多个装饰器对象包装。

装饰器模式的角色

  1. Component(组件):定义一个对象接口,可以给这些对象动态地添加职责。
  2. ConcreteComponent(具体组件):实现Component接口的具体对象,也就是被装饰的对象。
  3. Decorator(装饰器抽象类):实现Component接口,并持有一个Component对象的引用,其实际上是一个包装器。
  4. ConcreteDecorator(具体装饰器):具体的装饰器对象,负责给具体组件对象添加额外的职责。

代码示例(Java)

以下是一个简单的示例,假设我们有一个咖啡店,有不同种类的咖啡(ConcreteComponent),以及可以添加的各种调料(ConcreteDecorator)。

1. Component 接口

// 定义一个咖啡接口
public interface Coffee {
    double cost(); // 计算咖啡的价格
    String getDescription(); // 获取咖啡的描述
}

2. ConcreteComponent 具体组件

// 具体的咖啡类,实现 Coffee 接口
public class Espresso implements Coffee {
    @Override
    public double cost() {
        return 1.99; // Espresso 的价格
    }
    
    @Override
    public String getDescription() {
        return "Espresso"; // Espresso 的描述
    }
}

3. Decorator 装饰器抽象类

// 装饰器抽象类,实现 Coffee 接口
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
    
    public double cost() {
        return decoratedCoffee.cost();
    }
    
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}

4. ConcreteDecorator 具体装饰器

// 具体的调料装饰器类,扩展 CoffeeDecorator
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    @Override
    public double cost() {
        return super.cost() + 0.5; // 加牛奶的价格
    }
    
    @Override
    public String getDescription() {
        return super.getDescription() + ", Milk"; // 加牛奶的描述
    }
}

5. 使用示例

public class Main {
    public static void main(String[] args) {
        // 创建一个基础的 Espresso 对象
        Coffee espresso = new Espresso();
        System.out.println("Cost: $" + espresso.cost()); // 输出基础咖啡的价格
        System.out.println("Description: " + espresso.getDescription()); // 输出基础咖啡的描述
        
        // 加入牛奶
        Coffee milkEspresso = new MilkDecorator(espresso);
        System.out.println("Cost: $" + milkEspresso.cost()); // 输出加了牛奶的咖啡的价格
        System.out.println("Description: " + milkEspresso.getDescription()); // 输出加了牛奶的咖啡的描述
    }
}

在这个示例中,Espresso 是一个具体的咖啡对象(ConcreteComponent),MilkDecorator 是一个具体的装饰器对象(ConcreteDecorator),它扩展了 CoffeeDecorator 类并实现了 cost 和 getDescription 方法来添加额外的功能(加牛奶)。

装饰器模式的优点是可以灵活地给对象添加功能,而不需要改变其结构,同时遵循开闭原则(对扩展开放,对修改关闭)。