首页 > 其他分享 >装饰者模式

装饰者模式

时间:2022-12-03 11:12:07浏览次数:35  
标签:咖啡 obj System 模式 装饰 public println order

装饰者模式

星巴克咖啡订单项目:

1)咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack(浓缩咖啡)、LongBlack(美式咖啡)、Decaf(无因咖啡)

2)调料:Milk、Soy(豆浆)、Chocolate

3)要求在扩展新的咖啡种类的时候,具有良好的扩展性、改动方便、维护方便。

4)使用OO(面向对象)的方法来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以点单品咖啡+调料组合。

方案一 较差的传统方案

 

 

这种解决方案会造成类爆炸

方案二 对方案一进行改进

 

 

前面分析到方案一因为咖啡单品+调料组合会造成类爆炸,因此可以做改进,将调料内置到Drink类中,这样就不会造成类的数量过多。从而提高了代码的可维护性。

说明:milk,soy.chocolate可以设计为boolean类型,表示是否需要添加相应的调料。

方案二问题分析:

  1. 方案二可以控制类的数量,不至于造成类的数量过多。
  2. 在增加或者删除调料类的时候,代码的维护量很大(因为都要在同一个Drink类中进行修改)
  3. 考虑到用户可以添加多份调料的时候,可以将hasMilk 返回一个对应的int 类型
  4. 所以我们考虑使用装饰者模式

装饰者模式定义

 

 

 

 

 

 

代码演示:

package com.sky.decorator;

/**
 * 将各种单品咖啡做一个缓存层
 */
public class Coffee extends Drink {

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

package com.sky.decorator;

/**
 * 意大利咖啡 要继承缓存层
 */
public class Espresso extends Coffee {

    // 通过构造器,初始化意大利咖啡 描述 和 价格
    public Espresso(){

        setDes(" 意大利咖啡 ");
        setPrice(6.0f);
    }


}

package com.sky.decorator;

/**
 * 美式咖啡
 */
public class LongBlack extends Coffee {

    public LongBlack(){

        setDes(" 美式咖啡 ");
        setPrice(5.0f);
    }
}

package com.sky.decorator;

/**
 * 浓缩咖啡 单品咖啡
 */
public class ShortBlack extends Coffee {

    public ShortBlack(){

        setDes(" 浓缩咖啡 ");
        setPrice(4.0f);
    }
}

package com.sky.decorator;

/**
 * 无因咖啡
 */
public class Decaf extends Coffee {

    public Decaf(){

        setDes(" 无因咖啡 ");
        setPrice(3.0f);
    }
}

	package com.sky.decorator;

/**
 * 抽象类
 */
public abstract class Drink {

    private String des; // 描述
    private float price = 0.0f; // 价格

    // 添加set get 方法
    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();
}

package com.sky.decorator;

/**
 * 装饰者
 */
public class Decorator extends Drink {

    private Drink obj; // 被装饰者

    public Decorator(Drink obj){ // 体现的是一种组合关系

        this.obj = obj;
    }

    @Override
    public float cost() {
        // super.getPrice() 表示自己的价格,其中super.是可以不写的
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDes() {
        // 其中super.是可以不写的
        // obj.getDes() 表示输出被装饰者的信息
        return super.getDes() + " " + super.getPrice() + " " +  obj.getDes() + " " +  obj.getPrice();
    }
}

package com.sky.decorator;

/**
 * 调味品 巧克力
 */
public class Chocolate extends Decorator {
    public Chocolate(Drink obj) {
        super(obj);
        setDes(" 巧克力 ");
        setPrice(3.0f);
    }
}

package com.sky.decorator;

/**
 * 调味品 牛奶
 */
public class Milk extends Decorator {
    public Milk(Drink obj) {
        super(obj);
        setDes(" 牛奶 ");
        setPrice(2.0f);
    }
}

package com.sky.decorator;

/**
 * 调味品 豆浆
 */
public class Soy extends Decorator {

    public Soy(Drink obj) {
        super(obj);
        setDes(" 豆浆 ");
        setPrice(1.5f);

    }
}

package com.sky.decorator;

public class CoffeeBar {

    public static void main(String[] args) {

        // 使用装饰者模式点一份美式咖啡和两份牛奶

        // 1.先点一份美式咖啡
        Drink order = new LongBlack();
        System.out.println(" 描述:" + order.getDes());
        System.out.println(" 费用:" + order.cost());


        // 2.再加一份牛奶
        order = new Milk(order);
        System.out.println(" 描述:" + order.getDes());
        System.out.println(" 费用:" + order.cost());

        // 3.再加入一份巧克力
        order = new Chocolate(order);
        System.out.println(" 描述:" + order.getDes());
        System.out.println(" 费用:" + order.cost());

        // 3.再加入一份巧克力
        order = new Chocolate(order);
        System.out.println(" 描述:" + order.getDes());
        System.out.println(" 费用:" + order.cost());

        System.out.println("===================================");
        System.out.println("===================================");

        Drink order2 = new Decaf();
        System.out.println(" 描述:" + order2.getDes());
        System.out.println(" 费用:" + order2.cost());

        order2 = new Milk(order2);
        System.out.println(" 描述:" + order2.getDes());
        System.out.println(" 费用:" + order2.cost());


    }
}

 描述: 美式咖啡 
 费用:5.0
 描述: 牛奶  2.0  美式咖啡  5.0
 费用:7.0
 描述: 巧克力  3.0  牛奶  2.0  美式咖啡  5.0 2.0
 费用:10.0
 描述: 巧克力  3.0  巧克力  3.0  牛奶  2.0  美式咖啡  5.0 2.0 3.0
 费用:13.0
===================================
===================================
 描述: 无因咖啡 
 费用:3.0
 描述: 牛奶  2.0  无因咖啡  3.0
 费用:5.0

  

 

标签:咖啡,obj,System,模式,装饰,public,println,order
From: https://www.cnblogs.com/dongyaotou/p/16947178.html

相关文章

  • meta账号激活开发者模式
    meta账号激活开发者模式有两种方法:1.绑定信用卡2.绑定手机号,有两种渠道 2.1第一种如下图 进入下面的地址就可以看到setuptwo-factorauthenticati......
  • python 装饰器
    defadd(x,y):returnx+ydeflogger(fn):defwrapper(*args,**kwargs):print('调用前增强')ret=fn(*args,**kwargs)#参数解构......
  • C# AES CFB加解密模式兼容JAVA
    C#AESCFB加解密模式兼容JAVA代码片段最近在和java做对接的时候老是遇到加密使用java写的,需要我们使用C#来解密相关数据,AES加解密平常也在用,但是这种跨语言的应用还是比较......
  • Oracle数据库体系结构更改数据库的归档模式
    重做日志文件负责实例失败时的数据恢复,因为SGA中没有被保存的数据会全部丢失,使用重做日志文件就可以完全恢复事务。而归档日志进程用于介质恢复,比如磁盘损坏时,可以使用之前......
  • vmware虚拟机三种网络模式(桥接、NAT、仅主机)带图详解
    文章目录说明三种网络模式介绍Bridge桥接模式说明设置vmware网络适配器虚拟机网络修改为桥接模式查看桥接物理网卡IP信息虚拟机中配置ip特殊说明NAT网络地址转换说明设置......
  • 用设计模式来替代if-else(转)
    原文:https://www.cnblogs.com/DiDi516/p/11787257.html1、前言​ 物流行业中,通常会涉及到EDI报文(XML格式文件)传输和回执接收,每发送一份EDI报文,后续都会收到与之关联的......
  • (十六)备忘录模式
    1概述备忘录(Memento)模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。Originator(发起......
  • 数字化虚拟仿真教学系统,打造"互联网+"教学培训新模式
    随着互联网技术的不断发展,教育培训工作也迎来了发展的机遇和挑战。互联网有着实时性、交换性、共享性、开放性等特点,将教育培训与互联网相结合,增强了信息整合性、操作的便......
  • 设计模式之状态模式笔记
    刚看书看到的,关于一个设计模式的状态模式的不错的讲解,是以QQ的登陆.在线,忙碌,离线四个状态的一个说明,代码如下状态的接口类:publicinterfaceQQState{   voidhan......
  • 设计模式之职责链模式笔记
    这个模式用的不多,笔记之,病人去医院看病的例子,来自易说设计模式一书publicabstractclassDoctor{   publicabstractvoidseeDoctor(XiaoGongxiaoGong);   p......