装饰器模式【结构型】

装饰器模式是一种结构型设计模式,它允许通过将对象放入包装器中来为原始对象增强功能。 ​ 这些包装器(称为装饰器),能够在不改变原始对象代码的情况下,动态地为其添加新的行为和属性。

装饰器模式由 4 部分组成:

  1. 抽象构建

  2. 具体构建

  3. 装饰器

  4. 具体装饰角色

案例:在生活中我们需要提供一个咖啡点单系统。咖啡提供了描述信息个获取获取价格,如果说 我们提供了加牛奶的服务,在计算价格时就得床架很多相应的牛奶咖啡类了。也会出现类爆炸

这时就可以使用装饰着模式解决这个问题。

我们提供一个咖啡装饰器,使用装饰器模式做明显的特征就是 装饰器需要实现被装饰的产品,同时也需要将产品组合到装饰器中。

代码实现:

1、创建抽象构建【咖啡,Coffee】,提供获取名称和价格两个抽象方法

/**
 * 抽象组件
 **/
public interface Coffee {
​
    String getName();
​
    Double getPrice();
}

2、创建具体组件,咖啡的一种具体类型【卡布奇诺,KabuqinuoCoffee】,具体组件需要实现抽象组件

public class KabuqinuoCoffee implements Coffee {
    @Override
    public String getName() {
        return "卡布奇诺";
    }
​
    @Override
    public Double getPrice() {
        return 12.60;
    }
}

3、创建抽象装饰器【CoffeeDecorator】,同样需要实现抽象构建,这样在后面具体装饰器才有获取咖啡的名称和价格的方法。同时需要将抽象组件作为成员变量聚合到抽象装饰器中,目的是在某一个具体的咖啡组件上做增强,所以需要提前将具体的咖啡组件传递给装饰器。

/**
 * 装饰器
 * 需要实现 Coffee
 **/
public class CoffeeDecorator implements Coffee{
​
    /**
     * 原始咖啡,没有增强的咖啡
     **/
    private final Coffee coffee;
​
    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
​
    /**
     * 原始咖啡的姓名
     **/
    @Override
    public String getName() {
        return coffee.getName();
    }
​
    /**
     * 原始咖啡的价格
     **/
    @Override
    public Double getPrice() {
        return coffee.getPrice();
    }
}

装饰器的作用是做具体构建进行进一步的升级,所以说我们需要获取具体的产品,并且返回产品封装之后的信息所以说,就需要将抽象构建组合【聚合也合理】到装饰器,同时装饰器也需要实现或者继承抽象构建,这样子在后续的具体装饰角色在创建的时候就可以返回在抽象构建的基础上进一步升级了。

4、声明具体装饰器【牛奶咖啡】,在咖啡的基础上可以加牛奶

/**
 * 牛奶咖啡
 **/
public class MikeCoffee extends CoffeeDecorator{
    
    /**
     * 在创建构造器时需要将原始咖啡传递给装饰器
     **/
    public MikeCoffee(Coffee coffee) {
        super(coffee);
    }
​
    /**
     * 返回增强后的名称
     **/
    @Override
    public String getName() {
        return super.getName() + "加奶牛";
    }
​
    /**
     * 返回增强后的价格
     **/         
    @Override
    public Double getPrice() {
        return super.getPrice() + 3.50;
    }
}

5、测试

   public static void main(String[] args) {
        //初始化一杯卡布奇诺咖啡
        KabuqinuoCoffee kabuqinuoCoffee = new KabuqinuoCoffee();
        String kabuqinuoCoffeeName = kabuqinuoCoffee.getName();
        Double kabuqinuoCoffeePrice = kabuqinuoCoffee.getPrice();
        System.out.println("kabuqinuoCoffeeName = " + kabuqinuoCoffeeName);
        System.out.println("kabuqinuoCoffeePrice = " + kabuqinuoCoffeePrice);
​
        System.out.println("============================");
        //初始化一杯牛奶咖啡,在卡布奇诺的基础上加牛奶
        MikeCoffee mikeCoffee = new MikeCoffee(kabuqinuoCoffee);
        String mikeCoffeeName = mikeCoffee.getName();
        Double mikeCoffeePrice = mikeCoffee.getPrice();
        System.out.println("mikeCoffeeName = " + mikeCoffeeName);
        System.out.println("mikeCoffeePrice = " + mikeCoffeePrice);
    }
​
//测试结果
kabuqinuoCoffeeName = 卡布奇诺
kabuqinuoCoffeePrice = 12.6
============================
mikeCoffeeName = 卡布奇诺加奶牛
mikeCoffeePrice = 16.1
​
Process finished with exit code 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值