结构型设计模式 - 装饰者模式详解

基本定义

装饰者模式属于结构型模式,它可以动态的将新功能附加到对象上,同时又不改变其结构。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(OCP)。

模式结构

装饰者和被装饰者有相同的超类型,因为装饰者和被装饰者必须是一样的类型,利用继承是为了达到类型的匹配,而不是利用继承获取行为

  • Component:装饰者和被装饰者共同的父类,是一个接口或者抽象类,用来定义基本行为

  • ConcreteComponent:定义具体对象,即被装饰者

  • Decorator:抽象装饰者,继承自 Component,从外类来扩展 ConcreteComponent。对于 ConcreteComponent来说,不需要知道Decorator的存在,Decorator 是一个接口或抽象类

  • ConcreteDecorator:具体装饰者,用于扩展 ConcreteComponent

举例说明

在咖啡店客人想点一杯加两份糖一份牛奶的摩卡咖啡,各个商品的价格如下,我们需要根据用户点的咖啡、加的配料,动态的计算价格

商品 价格
拿铁咖啡(LatteCoffee) 4.5
摩卡咖啡(MochaCoffe) 5.5
糖(Sugar) 1.0
牛奶(Milk) 2.0

「实体类」 Coffee

public abstract class Coffee{
    public String des = "咖啡"; //描述
    private float price = 0.0f; //价格

    protected abstract float cost(); //计算费用

    //省略getter setter方法
}

「被装饰者」LatteCoffee

public class LatteCoffee extends Coffee{
    public LatteCoffee() {
        setDes("拿铁咖啡");
        setPrice(4.5f);
    }

    @Override
    protected float cost() {
        return getPrice();
    }
}

「被装饰者」MochaCoffee

public class MochaCoffee extends Coffee {
    public MochaCoffee() {
        setDes("摩卡咖啡");
        setPrice(5.5f);
    }

    @Override
    protected float cost() {
        return getPrice();
    }
}

「抽象装饰者」Decorator

public class Decorator extends Coffee {

    private Coffee coffee;

    public Decorator(Coffee drink) {
        this.coffee = drink;
    }

    @Override
    protected float cost() {
        return getPrice() + coffee.cost();
    }

    @Override
    public String getDes() {
        return coffee.getDes() + "加" + super.getDes();
    }
}

「具体装饰者」SugarDecorator

public class SugarDecorator extends Decorator{
    public SugarDecorator(Coffee coffee) {
        super(coffee);
        setDes("糖");
        setPrice(1.0f);
    }
}

「具体装饰者」MilkDecorator

public class MilkDecorator extends Decorator{
    public MilkDecorator(Coffee coffee) {
        super(coffee);
        setDes("牛奶");
        setPrice(2.0f);
    }
}

「测试类」Client

public class Client {
    /**
     * 点一杯 加两份糖一份牛奶的摩卡咖啡
     */
    @Test
    public void test01() {
        Coffee order = new MochaCoffee();
        System.out.println(order.getDes() + ",价格:" + order.cost());
        //加两份糖
        order = new SugarDecorator(new SugarDecorator(order));
        System.out.println(order.getDes() + ",价格:" + order.cost());
        //加一份牛奶
        order = new MilkDecorator(order);
        System.out.println(order.getDes() + ",价格:" + order.cost());
    }
}

「结果」result

摩卡咖啡,价格:5.5
摩卡咖啡加糖加糖,价格:7.5
摩卡咖啡加糖加糖加牛奶,价格:9.5

在 Java IO 流中的应用

在上图所示的关系中

  • 实体类是 InputStream

  • 被装饰者是FileInputStream、StringBufferInputStream、ByteArrayInputStream

  • 抽象装饰者是FilterInputStream

  • 具体装饰者是BufferInputStream、DataInputStream、LineNumberInputStream

具体使用如下:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\a.txt"));

装饰者模式总结

1、利用继承设计子类,只能在编译时静态决定,并且所有子类都会继承相同的行为;利用组合扩展对象,就可以在运行时动态的进行扩展。

2、装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被装饰者)的场合,都可以用装饰过的对象代替原始对象。

3、可以用一个或多个装饰者包装一个对象(被装饰者)。

4、装饰者可以在所委托的装饰者行为之前或之后加上自己的行为,以达到特定的目的。

5、被装饰者可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

6、装饰者会导致出现很多小对象,如果过度使用,会让程序变得复杂。

(0)

相关推荐

  • 设计模式(十)——组合模式(HashMap源码解析)

    设计模式(十)——组合模式(HashMap源码解析)

  • DercoratorPattern装饰者模式

    装饰者模式 1,定义 动态的给一个对象添加一些额外的职责. 装饰者模式通常有4个角色,就增加功能来说,装饰者模式比生成子类更加的灵活. Component:抽象构件.通常是一个接口或者抽象类,定义最核 ...

  • PHP设计模式之装饰器模式

    PHP设计模式之装饰器模式 工厂模式告一段落,我们来研究其他一些模式.不知道各位大佬有没有尝试过女装?据说女装大佬程序员很多哟.其实,今天的装饰器模式就和化妆这件事很像.相信如果有程序媛MM在的话,马 ...

  • 详解JAVA面向对象的设计模式 (七)、装饰模式

    装饰模式 Decorator 装饰模式比较简单,我就不单独写实现例子了.参考设计图去实现不是什么问题.建议可以写一写找找感觉. 在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修.相 ...

  • 3年工作必备 装饰器模式

    回复"000"获取大量电子书 大家好,我是老田,从今天开始,本公众号每周给大家送福利,送什么呢?肯定是技术书啦,没那么多花里胡哨的,参与方式见文末. 好啦,进入我们的主题,今天我给 ...

  • 结构型设计模式 - 组合模式详解

    基本介绍 1.组合模式(Composite Pattern)又叫部分整体模式,他创建了对象组的树形结构,将对象组合成树状结构以表示「整体 - 部分」的层次关系. 2.组合模式使得用户对单个对象和组合对 ...

  • 设计模式-原型模式详解

    一.原型模式的概念 原型模式属于创建型设计模式.当要创建的对象类型由原型实例确定时使用它,该实例被克隆以生成新对象. 此模式用于 1.避免客户端应用程序中的对象创建者的子类,如工厂方法模式. 2.避免 ...

  • 直播电商、直播购物,商城系统开发模式详解

    商城直播系统是在直播系统与商城系统的基础上开发出的一种新的模式,利用直播带货商城源码,可以搭建购物商城直播平台,这样做可以让消费者实现在看视频直播的同时看到自己喜欢的商品直接下单消费的功能. 电商平台 ...

  • 全网首发:涨停板低吸模式详解,低吸即涨停,掌握后从此告别追涨

    全网首发:涨停板低吸模式详解,低吸即涨停,掌握后从此告别追涨

  • 最全关于契约型私募基金运营模式详解(内部架构+规范体系)

    中国投行俱乐部[全球投行CEO大本营] 微信号:ibankclub 欢迎全球投行.VC.PE.并购.基金.券商.信托.银行.保险.租赁.投资等金融大咖关注中国投行第一品牌-中国投行俱乐部,寻找优质项目 ...

  • 涨停板战法两大模式详解:涨停当天买入与涨停次日买入

    涨停板模式优缺点深度对比 当日涨停时追入 次日择机再追入 优点 次日早盘冲高可出,只要涨停封得较死,或多或少都有利润全身而退. 有充足的时间对涨停个股进行详细分析,能够做到有的放矢,成竹在胸 缺点 事 ...

  • STM32启动模式详解

    一.三种boot启动模式: 一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式. ...

  • 设计模式-装饰器模式

    装饰器模式 定义 装饰器模式也叫包装模式 在不改变原有对象的基础上,把功能附加到对象上,提供了比继承更有弹性的替代方案 能够扩展原有对象的功能 属于结构型模式 生活中的例子 买煎饼 我们煎饼可以加鸡蛋 ...

  • 工程建设PPP、BOT、BT、TOT、TBT模式详解,先收藏再看

    一.什么叫BOT.BT.TOT.TBT和PPP投融资模式 1.BOT 即建造-运营-移交方式 这种方式最大的特点就是将基础设施的经营权有期限的抵押以获得项目融资,或者说是基础设施国有项目民营化.在这种 ...