设计模式之装饰者模式

基本介绍

装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)

模式原理

  1. 装饰者模式就像打包一个快递
    主体:比如:陶瓷、衣服 (Component) // 被装饰者
    包装:比如:报纸填充、塑料泡沫、纸板、木板(Decorator)
  2. Component 抽象主体,被装饰者,
  3. ConcreteComponent 具体的被装饰主体
  4. Decorator: 装饰者
    在如图的 Component 与 ConcreteComponent 之间,如果 ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。
    在这里插入图片描述

以星巴克咖啡订单为例运用装饰者模式

示例类图

在这里插入图片描述

示例代码

Component 抽象被修饰主体类

//饮品类
public abstract class Drink {
    private String des;
    private float price = 0.0f;

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    //计算费用的抽象方法
    //子类来实现
    public abstract float cost();
}

缓冲层咖啡类

//缓冲层咖啡类
public class Coffee extends Drink {
    @Override
    public float cost() {
        return super.getPrice();
    }
}

ConcreteComponent 具体被修饰主体类

//意大利咖啡类
public class Espresso extends Coffee {
    public Espresso() {
        setDes("意大利咖啡");
        setPrice(6.0f);
    }
}
//美式咖啡类
public class LongBlack extends Coffee {
    public LongBlack() {
        setDes("美国咖啡");
        setPrice(5.0f);
    }
}

装饰者

//佐料类
public class Decorator extends Drink {
    private Drink obj;

    public Decorator(Drink obj) {
        this.obj = obj;
    }

    @Override
    public float cost() {
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDes(){
        //输出被装饰者的信息
        return super.getDes() + ":" + super.getPrice() + " + " + obj.getDes();
    }
}

具体装饰者

//牛奶佐料类
public class Milk extends Decorator {
    public Milk(Drink obj) {
        super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }
}
//糖佐料类
public class Sugar extends Decorator {
    public Sugar(Drink obj) {
        super(obj);
        setDes("糖");
        setPrice(1.0f);
    }
}

客户端使用

public class CoffeeBar {
    public static void main(String[] args) {
        //1、点一杯意大利咖啡
        Drink order1 = new Espresso();
        System.out.println(order1.getDes()+" = "+order1.cost());
        //2、加奶
        order1 = new Milk(order1);
        System.out.println(order1.getDes()+" = "+order1.cost());
        //3、加糖
        order1 = new Sugar(order1);
        System.out.println(order1.getDes()+" = "+order1.cost());
        
       	System.out.println("=========================================");

        //1、点一杯美式咖啡
        Drink order2 = new LongBlack();
        System.out.println(order2.getDes()+" = "+order2.cost());
        //2、加两份奶
        order2 = new Milk(order2);
        order2 = new Milk(order2);
        System.out.println(order2.getDes()+" = "+order2.cost());
    }
}
//输出结果
//意大利咖啡 = 6.0
//牛奶:2.0 + 意大利咖啡 = 8.0
//糖:1.0 + 牛奶:2.0 + 意大利咖啡 = 9.0
//=========================================
//美国咖啡 = 5.0
//牛奶:2.0 + 牛奶:2.0 + 美国咖啡 = 9.0

使用装饰者模式之后,对于增加被装饰者或者增加装饰者都极为方便,只需要增加对应的类,被装饰者继承被装饰者的抽象类,装饰者继承装饰着的父类。不用改动代码,直接就可以在用户端使用,非常巧妙。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值