设计模式——装饰者模式(继承和接口的两种实现方式)

装饰者模式是一种用于动态添加或扩展对象功能的设计模式,它允许在不修改对象本身的情况下,通过装饰器对象来给原对象添加额外的职责。文章通过手抓饼的例子,展示了如何使用装饰者模式计算不同配料的手抓饼总价,强调了装饰者模式带来的灵活性和低耦合性,以及在系统扩展和维护中的优势。
摘要由CSDN通过智能技术生成

是什么?

场景案例:想必大家都吃过手抓饼吧,我们在点手抓饼的时候可以选择加培根、鸡蛋、火腿、肉松等等这些配菜,当然这些配菜的价格都不一样,那么计算总价就比较麻烦;

装饰者模式就是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即额外功能);

结构

抽象构件:定义一个抽象接口以规范准备接收附加责任的对象;

具体构件:实现抽象构件,通过装饰角色为其添加一些职责;

抽象装饰:继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能;

具体装饰:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任;

实现

通过继承

抽象构件

public abstract class HandGraspStore {
    //手抓饼店铺==>抽象构建
    private float price;
    private String desc;

    public HandGraspStore() {

    }

    public HandGraspStore(float price, String desc) {
        this.price = price;
        this.desc = desc;
    }

    public Float getPrice() {
        return price;
    }

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

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    public abstract float cost();
}

具体构件

public class HandGraspCake extends HandGraspStore{
    //手抓饼===>具体构件

    public HandGraspCake() {
        super(10,"手抓饼");
    }

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

抽象装饰

public abstract class Decorator extends HandGraspStore {
    //抽象装饰
    private HandGraspStore handGraspStore;

    public HandGraspStore getHandGraspStore() {
        return handGraspStore;
    }

    public void setHandGraspStore(HandGraspStore handGraspStore) {
        this.handGraspStore = handGraspStore;
    }

    public Decorator(HandGraspStore handGraspStore,float price,String desc) {
        super(price,desc);
        this.handGraspStore=handGraspStore;
    }
}

具体装饰

public class Egg extends Decorator{
    //鸡蛋===>具体装饰
    public Egg(HandGraspStore handGraspStore) {
        super(handGraspStore,1,"加一个鸡蛋");
    }

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

    @Override
    public String getDesc() {
        return super.getDesc()+getHandGraspStore().getDesc();
    }
}
public class Ham extends Decorator{
    //培根===>具体装饰
    public Ham(HandGraspStore handGraspStore) {
        super(handGraspStore,3,"加一个火腿");
    }

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

    @Override
    public String getDesc() {
        return super.getDesc()+getHandGraspStore().getDesc();
    }
}

用户使用

public class Customer {
    public static void main(String[] args) {
        HandGraspCake handGraspCake = new HandGraspCake();
        System.out.println(handGraspCake.getDesc()+handGraspCake.getPrice()+"元");
        System.out.println("==============================");
        Egg egg = new Egg(handGraspCake);
        System.out.println(egg.getDesc()+egg.cost()+"元");
        System.out.println("===============================");
        Ham ham = new Ham(egg);
        System.out.println(ham.getDesc()+ham.cost()+"元");
    }
}

通过接口

抽象构件

public interface IHandGraspCakeStore {
    float price();
    String desc();
    float cost();
}

 具体构件

public class IHandGraspStore implements IHandGraspCakeStore {
    @Override
    public float price() {
        return 10;
    }

    @Override
    public String desc() {
        return "手抓饼";
    }

    @Override
    public float cost() {
        return price();
    }
}

抽象装饰

public interface IDecoratorStore extends IHandGraspCakeStore {

}

具体装饰

public class IEggStore implements IDecoratorStore {

    private IHandGraspCakeStore handGraspCake;

    public IEggStore(IHandGraspCakeStore handGraspCake) {
        this.handGraspCake=handGraspCake;
    }



    @Override
    public float price() {
        return 1;
    }

    @Override
    public String desc() {
        return handGraspCake.desc()+"加鸡蛋";
    }

    @Override
    public float cost() {
        return price()+ handGraspCake.cost();
    }
}

用户使用

public class ICustomerDemo {
    public static void main(String[] args) {
        IHandGraspStore iHandGrasp = new IHandGraspStore();
        System.out.println(iHandGrasp.desc()+iHandGrasp.cost()+"元");
        System.out.println("================================");
        IEggStore iEgg = new IEggStore(iHandGrasp);
        System.out.println(iEgg.desc()+iEgg.cost()+"元");
        IEggStore eg = new IEggStore(iEgg);
        System.out.println(eg.desc()+eg.cost()+"元");
    }
}

 我们可以发现,这其实是一个反向控制,也就是说用户最终得到的是一个具体装饰类,而非我们的具体构建类,因为最终的金额计算或者说其他的操作逻辑,都是在具体装饰中进行统计并完成的;

优点

        1.装饰者模式可以带来比继承更加灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果,装饰者模式比继承更具有良好的扩展性,完美的尊姓开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任

        2.装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能

使用场景

1.当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时;

     不能采用继承的情况主要有以下两种:

        第一种是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;

        第二种是因为类不能继承(例如final类)

2.在不影响其他对象的情况下,需要以动态、透明的方式给单个对象添加职责;

3.当对象的功能要求可以动态地添加,也可以再动态地撤销时;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值