Java案例怎么实现装饰器模式?

wen java案例 48

Java装饰器模式实现详解

装饰器模式允许我们动态地给一个对象添加新的行为,而无需修改其原有类结构,下面通过咖啡店系统的案例来说明。

Java案例怎么实现装饰器模式?

基础结构设计

// 1. 抽象组件 - 饮料接口
interface Beverage {
    String getDescription();
    double cost();
}
// 2. 具体组件 - 基础咖啡
class Espresso implements Beverage {
    @Override
    public String getDescription() {
        return "浓缩咖啡";
    }
    @Override
    public double cost() {
        return 15.0;
    }
}
class HouseBlend implements Beverage {
    @Override
    public String getDescription() {
        return "综合咖啡";
    }
    @Override
    public double cost() {
        return 12.0;
    }
}
class DarkRoast implements Beverage {
    @Override
    public String getDescription() {
        return "深度烘焙咖啡";
    }
    @Override
    public double cost() {
        return 18.0;
    }
}

装饰器基类

// 3. 抽象装饰器
abstract class CondimentDecorator implements Beverage {
    protected Beverage beverage;
    public CondimentDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
    @Override
    public String getDescription() {
        return beverage.getDescription();
    }
    @Override
    public double cost() {
        return beverage.cost();
    }
}

具体装饰器实现

// 4. 具体装饰器 - 配料
class Milk extends CondimentDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 牛奶";
    }
    @Override
    public double cost() {
        return beverage.cost() + 3.0;
    }
}
class Mocha extends CondimentDecorator {
    public Mocha(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 摩卡";
    }
    @Override
    public double cost() {
        return beverage.cost() + 5.0;
    }
}
class Whip extends CondimentDecorator {
    public Whip(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 奶油";
    }
    @Override
    public double cost() {
        return beverage.cost() + 4.0;
    }
}
class Soy extends CondimentDecorator {
    public Soy(Beverage beverage) {
        super(beverage);
    }
    @Override
    public String getDescription() {
        return beverage.getDescription() + " + 豆浆";
    }
    @Override
    public double cost() {
        return beverage.cost() + 2.0;
    }
}

客户端使用示例

public class CoffeeShop {
    public static void main(String[] args) {
        // 基础咖啡
        Beverage espresso = new Espresso();
        System.out.println(espresso.getDescription() + " 价格: ¥" + espresso.cost());
        // 添加配料
        Beverage latte = new Milk(espresso);
        System.out.println(latte.getDescription() + " 价格: ¥" + latte.cost());
        // 多层装饰
        Beverage mochaLatte = new Mocha(latte);
        System.out.println(mochaLatte.getDescription() + " 价格: ¥" + mochaLatte.cost());
        // 复杂组合
        Beverage custom = new Whip(new Mocha(new Soy(new DarkRoast())));
        System.out.println(custom.getDescription() + " 价格: ¥" + custom.cost());
        // 动态添加额外配料
        Beverage doubleMochaLatte = new Mocha(new Mocha(new Milk(new HouseBlend())));
        System.out.println(doubleMochaLatte.getDescription() + " 价格: ¥" + doubleMochaLatte.cost());
    }
}

输出结果

浓缩咖啡 价格: ¥15.0
浓缩咖啡 + 牛奶 价格: ¥18.0
浓缩咖啡 + 牛奶 + 摩卡 价格: ¥23.0
深度烘焙咖啡 + 豆浆 + 摩卡 + 奶油 价格: ¥29.0
综合咖啡 + 牛奶 + 摩卡 + 摩卡 价格: ¥25.0

改进版本 - 使用泛型

// 更通用的装饰器实现
abstract class AbstractDecorator<T extends Beverage> implements Beverage {
    protected T component;
    public AbstractDecorator(T component) {
        this.component = component;
    }
    @Override
    public String getDescription() {
        return component.getDescription();
    }
    @Override
    public double cost() {
        return component.cost();
    }
}
// 使用泛型的具体装饰器
class Sugar<T extends Beverage> extends AbstractDecorator<T> {
    public Sugar(T component) {
        super(component);
    }
    @Override
    public String getDescription() {
        return super.getDescription() + " + 糖";
    }
    @Override
    public double cost() {
        return super.cost() + 1.0;
    }
}

装饰器模式的优势

  1. 开闭原则:无需修改现有类即可扩展功能
  2. 灵活性:可以在运行时动态组合不同的行为
  3. 避免类膨胀:避免了创建大量子类
  4. 细粒度控制:可以精确控制添加的功能

实际应用场景

  • Java I/O流BufferedReader 装饰 FileReader
  • GUI组件:添加滚动条、边框等功能
  • 日志系统:添加时间戳、格式化等功能
  • 权限控制:动态添加访问控制功能

这个案例展示了装饰器模式的核心思想:通过组合而不是继承来扩展对象的功能,既保持了类的单一职责,又提供了极大的灵活性。

抱歉,评论功能暂时关闭!