• 装饰者模式


    模式介绍

    装饰者模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法完整性的前提下,提供了额外的功能。

    模式优点

    1、动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
    2、装饰类和被装饰类可以独立发展,不会相互耦合,是继承的一个替代模式,可以动态扩展一个实现类的功能。

    模式缺点

    1、多层装饰比较复杂。

    使用场景

    1、扩展一个类的功能。
    2、动态增加功能,动态撤销。

    系统建模

    1、星巴克咖啡订单项目,咖啡和调料有很多搭配。
    2、创建一个饮料的接口Drink,和它的两个抽象子类Coffee、Decorator。
    3、Coffee抽象类中会有两种咖啡的实现类。
    4、Decorator充当装饰者,他下面会有Milk、Chocolate两种调料。

    系统实现

    /**
     * 饮料抽象类
     */
    public abstract class Drink {
        public String name;
        private float price = 0.0f;
    
        public abstract float cost();
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public float getPrice() {
            return price;
        }
    
        public void setPrice(float price) {
            this.price = price;
        }
    }
    
    /**
     * 咖啡大类
     */
    public class Coffee extends Drink {
        @Override
        public float cost() {
            return super.getPrice();
        }
    }
    
    /**
     * 意大利咖啡
     */
    public class Espresso extends Coffee{
        public Espresso(){
            setName("意大利咖啡");
            setPrice(12.0f);
        }
    }
    
    /**
     * 美式咖啡
     */
    public class LongBlack extends Coffee{
        public LongBlack(){
            setName("美式咖啡");
            setPrice(15.0f);
        }
    }
    
    /**
     * 调味大类
     */
    public class Decorator extends Drink {
        private Drink drink;
    
        public Decorator(Drink drink) {
            this.drink = drink;
        }
    
        @Override
        public float cost() {
            return super.getPrice()+drink.cost();
        }
    }
    
    /**
     * 牛奶调味品
     */
    public class Milk extends Decorator{
        public Milk(Drink drink) {
            super(drink);
            setName("牛奶调味品");
            setPrice(3.0f);
        }
    }
    
    /**
     * 巧克力调味品
     */
    public class Chocolate extends Decorator {
        public Chocolate(Drink drink) {
            super(drink);
            setName("巧克力调味品");
            setPrice(3.0f);
        }
    }
    
    /**
     * 客户端
     */
    public class Client {
        public static void main(String args[]){
            // 意大利咖啡
            Drink espressoCoffee = new Espresso();
            // 加一份牛奶
            espressoCoffee = new Milk(espressoCoffee);
            // 加一份巧克力
            espressoCoffee = new Chocolate(espressoCoffee);
            System.out.println("订单需要:"+espressoCoffee.cost()+"块钱!");
        }
    }
    结果:
    订单需要:18.0块钱!
    
  • 相关阅读:
    redis之不重启,切换RDB备份到AOF备份
    redis之持久化RDB与AOF
    redis之哨兵集群
    redis之订阅功能
    redis之基础命令
    Liunx之MySQL安装与主从复制
    Python邮件发送脚本(Linux,Windows)通用
    redhat6.4 gcc g++ rpm方式安装步骤
    LVS+Keepalived+Mysql+主主数据库架构[2台]
    监控mysql状态脚本
  • 原文地址:https://www.cnblogs.com/feiqiangsheng/p/12231303.html
Copyright © 2020-2023  润新知