一、装饰器模式简介
装饰器模式可以动态给一个对象添加一些额外的职责,同时又不改变其结构。就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
装饰器模式的应用场景:
1、在不修改源代码的情况下,扩展一个类的功能。 
2、实现动态增加功能,动态撤销。

二、示例演示
1、业务需求:
假设现在需要一个汉堡,主体是鸡腿堡,我们可以选择添加生菜、酱、辣椒等等许多其他的配料,同时根据所加的配料情况,从新计算价格。这种情况下就可以使用装饰者模式。

2、首先定义一个公共接口:所有汉堡和配料都必须实现该接口。(事实上汉堡本身也可以看作鸡腿堡的一个配料)

public interface Condiment {           String getName();      double getPrice();
}    

3、定义一个鸡腿堡的实现:(被装饰者的初始状态,有些自己的简单装饰)

public class ChickenBurger implements Condiment {    private String name;public ChickenBurger(){    //构造器name = "鸡腿堡";    }    public String getName(){return name;}public double getPrice() {    return 10;    //初始价格}    }    

4、再定义各个配料的具体情况,这些配料就是装饰者。
首先定义生菜配料:

public class Lettuce implements Condiment {    Condiment humburger;//持有一个被装饰者(汉堡)的引用,这是实现装饰器模式的关键public Lettuce(Condiment humburger){ //用具体的汉堡实例来初始化this.humburger = humburger;    }    public String getName() {    return humburger.getName()+" 加生菜";    }    public double getPrice() {    return humburger.getPrice()+1.5;    }    }    

在定义辣椒配料:

public class Chilli implements Condiment {    Condiment humburger;public Lettuce(Condiment humburger){ this.humburger = humburger;    }    public String getName() {    return humburger.getName()+" 加辣椒";    }    public double getPrice() {    return humburger.getPrice();//辣椒免费供应    }    } 

4、测试:

public class Test {    public static void main(String[] args) {    Condiment humburger = new ChickenBurger(); //初始化一个鸡腿汉堡实例   System.out.println(humburger.getName()+"  价钱:"+humburger.getPrice());   //测试单独加一种配料 Condiment lettuce = new Lettuce(humburger);    System.out.println(lettuce.getName()+"  价钱:"+lettuce.getPrice());    Condiment chilli = new Chilli(humburger);    System.out.println(chilli.getName()+"  价钱:"+chilli.getPrice());    //测试加多种配料humburger = new Lettuce(humburger); //加入生菜,然后返回装配好的实例humburger = new Chilli(humburger); //再加入辣椒,然后返回装配好的实例System.out.println(humburger.getName()+"  价钱:"+humburger.getPrice()); }    }    

三、总结
从上面的实现的方式发现这看起来像是一个对象一层一层包装起来一样,这也正是装饰模式别名“包装器”的由来。我的理解是这样的:
1、装饰模式的类Lettuce和Chilli其实是从公共接口类实现来的,也是用来装饰Condiment类的
2、同时在装饰类中有一个这样的构造方法:
public Lettuce(Condiment humburger){ 
        this.humburger = humburger;    
    }  
这个构造方法有点特殊的,参数是Condiment类型,利用多态特性,这个使得一层一层装饰成为了可能,也就是通过不断的给一个ChickenBurger对象增加功能变得极其方便;
3、还有一点就是体会一下在测试方法中具体使用。
humburger = new Lettuce(humburger); //加入生菜,然后返回装配好的实例
humburger = new Chilli(humburger); //再加入辣椒,然后返回装配好的实例
可以看出,我们每次用装饰后的对象去覆盖原对象,这样做的实现原理是利用了多态性。即无论Lettuce类对象还是Chilli类对象,都是一个Condiment的实例。

转载于:https://www.cnblogs.com/kangsir/p/6653226.html

java设计模式之装饰器模式相关推荐

  1. (设计模式七)java设计模式之装饰器模式

    一.简介: 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类 ...

  2. java设计模式之 装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  3. Java 设计模式之装饰器模式

    装饰器模式用于给原有对象增加新功能的场景, 拿食物冰淇淋,香草巧克力作为例子,给冰淇淋加香草,或者加巧克力,或者加香草和巧克力. 首先定义一个食物接口: /*** 装饰类和被装饰类共同继承的抽象类* ...

  4. java设计模式之装饰器模式(包装器模式)

    显然设计模式往往追求开闭原则,所以往往是面向接口编程,那么万事万物就是先写接口,把需求弄出来,这里以一辆车子在陆地上跑为基础,对它进行装饰,使它可以具备更多的"功能",达到装饰的效 ...

  5. 设计模式学习----装饰器模式

    这两天本来是自在学习java collection Framework的Fail Fast底层机制,看到核心的部分时,突然意识到设计模式的问题,上大学到现在我还没有真正理解过设计模式的概念,于是用了大 ...

  6. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  7. 【设计模式】装饰器模式的使用

    问题来源 我们在进行软件系统设计的时候,有一些业务(如下图,一些通用的非功能性需求)是多个模块都需要的,是跨越模块的.把它们放到什么地方呢? 最简单的办法就是把这些通用模块的接口写好,让程序员在实现业 ...

  8. go设计模式之装饰器模式

    go设计模式之装饰器模式 再写这篇文章时,我已经看了很多其他人发表的类似文章,大概看了这么多吧. 亓斌的设计模式-装饰者模式(Go语言描述) jeanphorn的Golang设计模式之装饰模式 七八月 ...

  9. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

最新文章

  1. 线性代数可以速成吗_广播/学习吉他速成靠谱吗?真的可以速成吗?
  2. linux 多线程编程笔记
  3. sonar findbugs plugin源码研究
  4. 你买过假芯片吗?元器件专家为您揭秘假冒芯片的套路!
  5. 十余位权威专家深度解读,达摩院2019十大科技趋势点燃科技热情
  6. 第49课 大大大(纯小数变整数) 《小学生C++趣味编程》
  7. python发送邮件程序
  8. 让IE6支持min-width和max-width的方法
  9. 【控制】动力学建模简介 --> 牛顿-欧拉 (Newton-Euler) 法和拉格朗日 (Lagrange) 法
  10. 【Linux设备驱动】如何挂载和卸载驱动 lsmod insmod rmmod和modprobe
  11. python xlwt使用_Python使用xlwt模块 操作Excel文件
  12. 易语言禁止服务器,禁止指定程序联网易语言源码
  13. Win10开电脑热点以后手机连接会IP配置失败或者一直显示获取IP中
  14. 直接让Windows注销的脚本
  15. 从0到1做好KOL运营实操
  16. 安卓打开rpm文件_android打开文件及打开方式(打开程序列表) | 学步园
  17. the kth number第几大数问题
  18. 云原生之史上最全K8S环境搭建(强烈建议收藏)
  19. 手机cpu性能天梯图2023 手机cpu处理器排行榜2023
  20. 中文自然语言处理向量合集(字向量,拼音向量,词向量,词性向量,依存关系向量)

热门文章

  1. 华为×××+IPSEC实现安全连接
  2. JAVA性能诊断与调优
  3. linux常见问题解答汇总
  4. Visio替代图表工具 - 为什么Visual Paradigm Online?
  5. Java线程入门第三篇
  6. 【刷算法】整数中1出现的次数(从1到n整数中1出现的次数)
  7. vue项目通过命令行传参实现多环境配置(基于@vue/cli)
  8. 国内IDC即将迎来快速增长时期
  9. 《Linux嵌入式实时应用开发实战(原书第3版)》——3.5 Linux文件系统
  10. 【COCOS2D-X(2.X) 游戏开发系列之一】COCOS2DX(V2.X)与(V1.X)的一些常用函数区别讲解!在2.X版CCFILEDATA类被去除等...