设计模式(java)--3.装饰者模式

1.装饰者模式是什么

装饰者模式定义比较抽象,我们可以举一个经典的例子来说明。奶茶店里有x种奶茶和y种配料。每一个产品用一种x和y中的1个或多个配料组成。请问怎么实现上述的功能?

方案一:x中的奶茶和y种配料,把所有搭配情况枚举出来,为每一个搭配方案定义一个类 ,显然,这种方式稍加改动就会让类暴炸,不妥

方案二:超类drink中把所有的种类调料都内置到超类中。把y个配料,内置进去,但他们都是布尔类型的,在下面定义的方法用于判断,是否扩展类中是否有他们,或者是要加什么配料,同时是否要加钱。但这个方案有缺点,比如增删配料种类,如果要引入一个配料,就要改动这个超类。也就是新功能的引入,会影响原有功能,原有代码。这样就会在改动原有功能时,所有的引入都会产生bug,都有可能引入bug。

方案三:我们可以设计为装饰者模式—给一个对象动态地、透明地添加职能。比如2份巧克力+一份牛奶这种搭配。先new一个单品对象,然后包装到Milk再然后包装到Chocolate,在包装在Chocolate里面,具体的费用计算是通过,代用最外层cost方法去获取,他会自己去获取自己里面包装的费用,然后一级级递归,去调用所有费用,从而获取所有费用
通过这种方式结构,你会发现当调料很多的情况下,任意他随意组合,我们都可以通过这种递归的方式获取所有的费用。不像第一种方式一样,每新一个组合就要扩展一个类,导致类爆炸。而且你引入一个调料的时候,只需要在上面说的具体的调料上去扩展一个出来就行了,引入新调料的时候,不会对原有的功能造成任何影响。它引入自己引入自己,不会对原有代码造成影响。

2.类图

在这里插入图片描述

3.案例代码实现

抽象类Drink-----Component

public abstract class Drink {
    private String describle="";
    private double price=0;

    public String getDescrible() {
        return describle;
    }

    public void setDescrible(String describle) {
        this.describle = describle;
    }

    public double getPrice() {
        return price;
    }

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

    public  abstract  double cost();
}

牛奶类和咖啡类-------ConcreteComponent

public class Milk extends Drink {
    public Milk() {
        super.setDescrible("10元牛奶");
        super.setPrice(10);
    }

    @Override
    public double cost() {
        return super.getPrice();
    }
}
public class Coffee extends Drink {
    public Coffee() {
        super.setDescrible("8元咖啡");
        super.setPrice(8);
    }

    @Override
    public double cost() {
        return super.getPrice();
    }
}

Decorator类

public  class Decorator extends Drink {
    private Drink Obj;//注意这里面有个父类的对象,因为这是个装饰者
    public Decorator(Drink Obj){//所以实现这个装饰者时必须带入这个Drink对象放进去
        this.Obj=Obj;
    };
    @Override
    public  double cost(){
        return super.getPrice()+Obj.cost();
    }
    @Override
    public String getDescrible()
    {
        return super.getDescrible()+"-"+super.getPrice()+"&&"+Obj.getDescrible();
    }
}

Pearl类和Jelly类—ConcreteDecorator

public class Pearl extends Decorator {
    public Pearl(Drink Obj) {
        super(Obj);
        super.setDescrible("3元珍珠");
        super.setPrice(3);
    }
}
 */
public class Jelly extends Decorator {
    public Jelly(Drink Obj) {
        super(Obj);
        super.setDescrible("2元果冻");
        super.setPrice(2);
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        //订单:2元果冻+3元珍珠+10元牛奶 测试
        Drink d1=new Jelly(new Pearl(new Milk()));
        System.out.println(d1.cost());
        System.out.println(d1.getDescrible());
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值