装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。我们通过下面的实例来演示装饰器模式的用法。我们的实例是实现餐馆点餐点,基础食物:米饭,你可以搭配啤酒,可乐.鱼或者蔬菜.

  • 意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

  • 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

  • 何时使用:在不想增加很多子类的情况下扩展类。

  • 如何解决:将具体功能职责划分,同时继承装饰者模式。

  • 关键代码:
  • 1、Beverage(材料) 类充当抽象角色,不应该具体实现。
  • 2、修饰类引用和继承 Beverage(材料) 类,具体扩展类重写父类方法。

  • 应用实例:
    • 1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。
    • 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。
  • 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

  • 缺点:多层装饰比较复杂。

  • 使用场景:
    • 1、扩展一个类的功能。
    • 2、动态增加功能,动态撤销。

注意事项:可代替继承。

代码示例

如上面所说,我们要实现参观点餐的需求,使用啤酒.鱼等辅助食材来装饰米饭(Rich)对象,要求这些材料具有相同的基类,那么下面我们先定义Beverage(材料类).

package com.zhoutao123.design.pattern.decorator;/*** 材料*/
public abstract class Beverage {private String desc = "未知食材";// 抽象方法,返回价钱public abstract float getCost();// 返回描述public  String getDesc(){return desc;}
}

然后我们定义米饭,米饭需要继承Beverage类

package com.zhoutao123.design.pattern.decorator;/*** 定义米饭*/
public class Rice extends Beverage{@Overridepublic String getDesc() {return "米饭,";}@Overridepublic float getCost() {return 12;}
}

定义一些其他食材.

package com.zhoutao123.design.pattern.decorator;/*** 定义啤酒*/
public class Beer extends Beverage {private Beverage beverage;public Beer(Beverage beverage) {this.beverage = beverage;}@Overridepublic String getDesc() {return beverage.getDesc()+"Beer,";}@Overridepublic float getCost() {return 0.2f + beverage.getCost();}
}

剩下的重复性动作就不在定义了,可以仿照Beer一次实现Cola(可乐) Fish(鱼) Vegetable(蔬菜)由于这是示例,代码比较简单,就不做过多的说明了,大致可以看下UML

  • getDesc() 获取商品描述
  • getCost() 获取商品的价格

下面看一些测试代码,可以看到可以使用随意的商品修饰Rich,而不用担心耦合.基础Rich需要什么,我么就可以去装饰它.

package com.zhoutao123.design.pattern.decorator;/*** 测试装饰者模式*/
public class TestDecorator {public static void main(String[] args) {// 首先定义米饭System.out.println("------------一个普通的晚餐订单---------------");Beverage beverage = new Rice();//分别用啤酒,可乐和鱼等食物装饰米饭// 得到一份晚餐beverage = new Beer(beverage);beverage = new Fish(beverage);beverage = new Cola(beverage);// 显示晚餐列表System.out.println(beverage.getDesc());// 显示晚餐总金额System.out.println(beverage.getCost());// 一位素食主义者的订单System.out.println("------------一位素食主义者的订单---------------");Beverage food = new Rice();food = new Vegetables(food);// 计算价钱和想清单// 显示晚餐列表System.out.println(food.getDesc());// 显示晚餐总金额System.out.println(food.getCost());}}

结果如下,(float类型产生的误差请忽略):

------------一个普通的晚餐订单---------------
米饭,啤酒,红烧鱼,可乐,
13.400001
------------一位素食主义者的订单---------------
米饭,Vegetables,
12.5

转载于:https://www.cnblogs.com/zhoutao825638/p/10382264.html

设计模式系列之装饰模式(Decorator Pattern)相关推荐

  1. 二十四种设计模式:装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern) 介绍 动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活. 示例 有一个Message实体类,某个对象对它的操作有Insert ...

  2. 七、装饰模式(Decorator Pattern)

    一.介绍 意图:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活. 主要解决:使用继承实现类的功能的扩展,有时子类会过多的问题. 应用实例: 1.一幅照片,将它放入玻 ...

  3. 设计模式-装饰模式(Decorator Pattern)

    Attach additional responsibilities to an object dynamically keeping the same interface.Decorators pr ...

  4. 设计模式实践系列 (3) - 装饰模式 ( Decorator )

    用途 用于动态地给一个对象添加一些额外的职责. 就增加功能来说, Decorator模式相比生成子类更为灵活.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 纯粹的装饰模式很难 ...

  5. C#设计模式系列:装饰模式(Decorator)

    1. 装饰模式简介 装饰模式动态地给一个对象添加额外的职责.例如一幅画有没有画框都可以挂在墙上,画就是被装饰者.但是通常都是有画框的.在挂在墙上之前,画可以被蒙上玻璃,装到框子里,所以在画上加一层画框 ...

  6. 基于东北F4的设计模式情景剧——第一幕 装饰模式(Decorator Pattern)

    第一场 难题未解 布景:铁岭,晴天,午后,风.在一幢还算气派的写字楼的三层外墙上,挂着一条红色横幅,上面用歪歪扭扭的毛笔字写着"东北F4软件外包工作室".大风中,那早已褪色的条幅剧 ...

  7. 设计模式之略见一斑(装饰模式decorator)

    标头:(引自设计模式) 为了扩展代码库,通常给它添加新类或者新方法.有时候,你也许不希望在运行时候使用新行为来组合对象.Interpreter模式允许你组合可执行对象,这个对象的行为可能变化会非常快. ...

  8. 《研磨设计模式》chap22 装饰模式Decorator(4)AOP+总结

    1. AOP面向方面编程 共性功能 AOP调用示意图 public class SaleModel { private String goods; //销售的商品 public String getG ...

  9. 《研磨设计模式》chap22 装饰模式Decorator(1)模式简介

    场景:算员工奖金,各种奖金,有个人销售奖,团队奖,环比增加销售奖等等 1. 正常编码 public class Prize {//计算某人在某段时间内的奖金,有些参数在演示中并不会使用, public ...

最新文章

  1. 【人工智能】人工智能时代的道路选择 | 焦点评论
  2. ASCII码转换成特殊字符
  3. 前端如何高效的与后端协作开发
  4. 天翼云从业认证(4.10)网络直播场景解决方案(CDN)
  5. 八十四、SpringBoot微服务Dubbo和Zookeeper分布式
  6. JSR-308和Checker框架为jOOQ 3.9添加了更多类型安全性
  7. Java高级语法笔记-库的使用(jar)
  8. Java Socket分发服务负载均衡
  9. iOS 6分享列表——UIActivityViewController详解
  10. 对于placeholder浏览器兼容性(包括密码输入框)解决办法
  11. 拉普拉斯矩阵(Laplacian Matrix) 及半正定性证明
  12. 微信小程序 指纹识别
  13. c++ 栈 stack 用法
  14. 充分利用微博加快社区发展
  15. Ubuntu添加和设置默认中文字体
  16. LTE-TDD资源调度(1)-QCI、GBR和Non-GBR
  17. 交换机(三层)接入层、汇聚层和核心层交换机的特点
  18. 网吧无盘系统服务器安装,网吧网络无盘系统的安装方法
  19. 计算机组装硬件要求,组装电脑必懂的硬件知识,全是干货,教你选购硬件不求人...
  20. vue按钮移上去显示提示_vue 鼠标移入移出事件(移入出现按钮),element-ui表格移入移出...

热门文章

  1. Flutter 启动图体验优化,无闪烁
  2. web app 框架
  3. Micropython ESP32驱动CH455控制4位数码管
  4. dpresult在python中什么意思_动态规划(DP)的整理-Python描述
  5. 以太网监控2022年应当关注的关键挑战和解决方案
  6. 通过VLC产生multicast RTP 流
  7. 循环链表 +(约瑟夫环)
  8. 【警告】chunk base [mini-css-extract-plugin] Conflicting order between:
  9. java计算机毕业设计疆域特色农家乐系统MyBatis+系统+LW文档+源码+调试部署
  10. sqlserver高可用方案_高可用数据库主从复制延时的解决方案