zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

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

     装饰者模式类似于打包一个快递。

    主体(Component):陶瓷、衣服。

    包装(Decorator):报纸填充、塑料泡沫、纸板、木板。

     这边的Component主体一般是抽象的,因为具体的主体肯定是不少的,所以编码中一般是抽象类,具体子类ConcreteComponent继承这个抽象类(如果具体主体的分类超级多,中间可以再加层抽象类作为缓冲层,提取相同的部分)。Decorator也是需要继承主体类并聚合一个主体类。

    以上说法十分抽象,例如有个例子:

    1、咖啡店有很多咖啡总类,Espresso, ShortBlack,LongBlack, Decaf。

    2、调料,milk(牛奶), soy(豆浆), chocolate(巧克力)

    假如我点了一份LongBlack,点了两个巧克力和牛奶作为调料。现在需要用装饰者模式实现订单的组合以计算费用。我们便以上面描述的装饰者模式的思路来用代码实现。

    Drink.java

    public abstract class Drink {
        //描述
        public 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();
    }

    Coffee.java

    public abstract class Coffee extends Drink {
        @Override
        public float cost() {
            return super.getPrice();
        }
    }

    这边的coffee就相当于上面说的缓冲层,因为,drink还分很多种,有果汁、茶、咖啡。 

    LongBlack.java(这个是具体的咖啡)

    public class LongBlack extends Coffee{
        public LongBlack(){
            setDes("LongBlack");
            setPrice(5.0f);
        }
    }

    Decorator.java

    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();
        }
    }

    Chocolate.java

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

    Milk.java

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

    Client.java

    public class Client {
        public static void main(String[] args) {
            //1、先点一份LongBlack
            Drink order = new LongBlack();
            System.out.println("费用1=" + order.cost());
            System.out.println("描述=" + order.getDes());
    
            //2、加入一份牛奶
            order = new Milk(order);
            System.out.println("order 加入一份牛奶后 费用=" + order.cost());
            System.out.println("描述=" + order.getDes());
    
            //3、加入一份巧克力
            order = new Chocolate(order);
            System.out.println("order 加入一份巧克力后 费用=" + order.cost());
            System.out.println("描述=" + order.getDes());
    
            //4、加入一份巧克力
            order = new Chocolate(order);
            System.out.println("order 加入一份巧克力后 费用=" + order.cost());
            System.out.println("描述=" + order.getDes());
        }
    }

    输出的结果:

    费用1=5.0
    描述=LongBlack
    order 加入一份牛奶后 费用=7.0
    描述=牛奶 2.0 && LongBlack
    order 加入一份巧克力后 费用=10.0
    描述=巧克力 3.0 && 牛奶 2.0 && LongBlack
    order 加入一份巧克力后 费用=13.0
    描述=巧克力 3.0 && 巧克力 3.0 && 牛奶 2.0 && LongBlack

    在代码可以看出来,以上LongBlack(主体)中的getDes()和cost()是直接返回,Decorator实例中的getDes()和cost()主要是递归的形式,遇到具体的主体,递归停止。

  • 相关阅读:
    windows系统切换jdk,修改java_home无效情况
    Cannot instantiate interface org.springframework.context.ApplicationListener
    MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)
    ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET
    EF TO MYSQL 无法查询中文的解决方法
    HttpWebRequest post请求获取webservice void数据信息
    This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms. 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分 解决方案
    MySQL 5.7.13解压版安装记录 mysql无法启动教程
    C# udpclient 发送数据断网后自动连接的方法
    汽车XX网站秒杀抢购代码
  • 原文地址:https://www.cnblogs.com/chenmz1995/p/12441581.html
Copyright © 2011-2022 走看看