设计模式之装饰者模式 简单实例+理解

设计模式之装饰者模式 简单实例+理解

仅代表我个人理解 下面是一个示例 我们点咖啡时可以选择调料 如下:
饮料: 咖啡
材料: 砂糖 牛奶

那我们是不是有 咖啡+砂糖 咖啡+牛奶 咖啡+砂糖+牛奶 咖啡 4种选择
以咖啡为父类 其他三种以子类形式继承父类 对应实现各自的需求 但是随着材料增多 组合增加 子类过多 会非常棘手 所以使用装饰者模式,顾名思义,我们准备一杯咖啡,然后用调料来装饰它,从代码的层面来讲,我们写一个需要装饰的装饰者类,然后只需要写对应装饰品类,需要哪个装饰品就将他放到装饰者类中。

装饰模式的基本uml图
装饰者模式

看的出来 如果需要加材料 只需要再写一个类就行了 不用担心组合的问题 至于为什么 上代码(可以直接将代码复制 并粘贴到包下 会自动生成类)

抽象类Coffee

//之所以使用抽象类 因为可能不止一个抽象对象
public  abstract class Coffee {

    public abstract String create();

    public abstract int price();

}

装饰者类

//装饰者类
public class CoffeeDecorator extends Coffee {

    private Coffee coffee;

    public CoffeeDecorator(Coffee coffee){
        this.coffee=coffee;
    }

    @Override
    public String create() {
          return coffee.create();
    }

    @Override
    public int price() {
        return coffee.price();
    }
}

星巴克咖啡

//星巴克
public class StarbucksCoffee extends Coffee {
    @Override
    public String create() {
        return "一杯星巴克";
    }

    @Override
    public int price() {
        return 20;
    }
}

瑞幸咖啡

public class LuckyCoffee extends Coffee {
    @Override
    public String create() {
        return "一杯瑞幸咖啡";
    }

    @Override
    public int price() {
        return 10;
    }
}

牛奶

public class Milk extends CoffeeDecorator {
    public Milk(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String create() {
        return super.create()+"加一杯牛奶";
    }

    @Override
    public int price() {
        return super.price()+2;
    }
}

public class Sugar extends CoffeeDecorator {
    public Sugar(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String create() {
        return super.create()+"加一勺糖";
    }

    @Override
    public int price() {
        return super.price()+1;
    }
}

demo测试类

public class demo {

    public static void main(String[] args) {

        Coffee luckyCoffee = new LuckyCoffee();

        luckyCoffee=new Ice(luckyCoffee);
        luckyCoffee=new Milk(luckyCoffee);
        luckyCoffee=new Sugar(luckyCoffee);
        luckyCoffee=new Sugar(luckyCoffee);
        luckyCoffee=new Milk(luckyCoffee);

        Coffee starbucksCoffee = new StarbucksCoffee();

        starbucksCoffee=new Milk(starbucksCoffee);
        starbucksCoffee=new Sugar(starbucksCoffee);
        starbucksCoffee=new Sugar(starbucksCoffee);
        starbucksCoffee=new Milk(starbucksCoffee);
        starbucksCoffee=new Ice(starbucksCoffee);



        System.out.println(luckyCoffee.create());
        System.out.println(luckyCoffee.price());
        System.out.println(starbucksCoffee.create());
        System.out.println(starbucksCoffee.price());
    }

}

运行结果;

一杯瑞幸咖啡加冰加一杯牛奶加一勺糖加一勺糖加一杯牛奶
17
一杯星巴克加一杯牛奶加一勺糖加一勺糖加一杯牛奶加冰
27

程序结束 在这之中有一个疑问 为什么装饰类要使用静态代理呢?

换一个角度思考 如果不适用 那么我们的装饰品类应该是这样的

//在实现类里写装饰也可以 但是每个都要写 很麻烦 所以统一写到decorator中
public class Ice extends Coffee{
    private Coffee coffee;

    public Ice(Coffee coffee){
        this.coffee=coffee;
    }

    @Override
    public String create() {
        return coffee.create()+"加冰";
    }

    @Override
    public int price() {
        return coffee.price()+1;
    }

}

每一个装饰品类都要写静态代理 非常麻烦 所以统一写一个 效率更高(个人理解)
而且使用装饰者模式可以想加多少加多少 例如 我想加5份牛奶 那只要Milk创建5次即可
如果不使用装饰者模式 代码上就要做很大的改动

附加

1.装饰者模式是 is-a 的实现 (继承)
2.实现了开闭原则 对修改关闭 对拓展开放
3.抽象类的作用是可以让这个类有更多的实现 如果只有一种实现的情况 可以不写抽象类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值