装饰器模式实现咖啡店(Java代码实例)

目录

装饰器模式

应用场景

一点思路

装饰器模式结构视图

实例类图

解题程序代码

程序运行结果


装饰器模式

装饰器模式是为了运行时动态的扩展一个类的功能。它谨循开闭原则,它实现的关键是继承和组合的结合使用,解耦对象之间的关系。装饰器模式充分展示了组合的灵活。利用它来实现扩展。它同时也是开闭原则的体现。 如果对某个类实现运行时功能动态的扩展, 这个时候就可以考虑使用装饰器模式。


应用场景

有一个咖啡店,销售各种各样的咖啡,拿铁,卡布奇洛,蓝山咖啡等,在冲泡前,会询问顾客是否要加糖,加奶,加薄荷等。这样不同的咖啡配上不同的调料就会卖出不同的价格。采用装饰器模式实现以下要求:

(1)实现给出装饰器模式结构视图。

(2)给出该实例类图及代码实现。


一点思路

Tips:由于不同的咖啡和不同的调料得各种任意组合,使得出现类爆炸的现象。为了规避这个问题,我们可以考虑把各种调料当作属性加入到Coffee这个抽象类中,接着在实现类中计算价格和名字时,分别判断是否加入了各种调料包,得到不同的名字和价格。

稍后我们会用到开闭原则继承和组合

开闭原则是面向对象的一个基本设计原则,即:类应该对修改关闭,对扩展开放。

假如cofee和它的一众实现拿铁,卡布奇洛,蓝山来自第三方类库,并且这个类库已经很适合且实用了。 而我们为了得到加入不同调料的咖啡的名字和价格,我们就得修改这些实现,而这样的修改,总是免不了改变稳定性。对原本的系统来说也是一种风险! 所以我们应该对修改关闭,对扩展开放。


装饰器模式结构视图


实例类图


解题程序代码

/** *@Author:XZIT_XX*/
public abstract class Coffee {
    /** * 获取咖啡得名字 */
    public abstract String getName();
    /** * 获取咖啡的价格*/
    public abstract double getPrice();
}


public abstract class Coffee {
    // 是否加了牛奶
    protected boolean addedMilk;
    // 是否加了糖
    protected boolean addedSugar;
    // 是否加了薄荷
    protected boolean addedMint;
    /** * 获取咖啡得名字*/
    public abstract String getName();
    /** * 获取咖啡的价格*/
    public abstract double getPrice();
}


public class BuleCoffee extends Coffee {
    @Override
    public String getName() {
        StringBuilder name = new StringBuilder();
        name.append("蓝山");
        if (addedMilk) {
            name.append("牛奶");
        }
        if (addedMilk) {
            name.append("薄荷");
        }
        if (addedSugar) {
            name.append("加糖");
        }
        return name.toString();
    }
    @Override
    public double getPrice() {
        double price = 10;
        if (addedMilk) 
            price += 1.1;
        if (addedMilk) 
            price += 3.2;
        if (addedSugar) 
            price += 2.7;
        return price;
    }
}


public abstract class CoffeeDecorator implements Coffee {
    private Coffee delegate;
    public CoffeeDecorator(Coffee coffee) {
        this.delegate = coffee;
    }
    @Override
    public String getName() {
        return delegate.getName();
    }
    @Override
    public double getPrice() {
        return delegate.getPrice();
    }
}


public class MilkCoffeeDecorator extends CoffeeDecorator {
    public MilkCoffeeDecorator(Coffee coffee) {
        super(coffee);
    }
    @Override
    public String getName() {
        return "牛奶, " + super.getName();
    }
    @Override
    public double getPrice() {
        return 1.1 + super.getPrice();
    }
}


public class App {
    public static void main(String[] args) {
        // 得到一杯原始的蓝山咖啡
        Coffee blueCoffee = new BlueCoffee();
        System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
        // 加入牛奶
        blueCoffee = new MilkCoffeeDecorator(blueCoffee);
        System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
        // 再加入薄荷
        blueCoffee = new MintCoffeeDecorator(blueCoffee);
        System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
        // 再加入糖
        blueCoffee = new SugarCoffeeDecorator(blueCoffee);
        System.out.println(blueCoffee.getName() + ": " + blueCoffee.getPrice());
    }
}

程序运行结果

Guess you like

Origin blog.csdn.net/Luoxiaobaia/article/details/120556532
Recommended