手抓饼加生菜加鸡蛋的装饰器模式
装饰器模式
装饰器模式(Decorator Patter),也称为包装模式(Wrapper Pattern)是指在不改变原有对象的基础之上,将功能附加在对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
装饰器模式的核心是功能扩展。使用装饰器可以透明且动态地扩展类的功能。
下面是通用的UML类图:
生活中的应用场景
看完上面的概念以及类图可能比较抽象,接下来我会举一个生活中的场景,来通俗易懂的讲解装饰器模式。
我们在早上上班途中,往往会在公司门口买一个手抓饼,然后带到工位上慢慢吃,相信很多小伙伴有过类似的经历。那么一个手抓饼什么都不加就是五块钱,我们把这个叫做标配,当然也可以按照你的喜好做一些定制化的需求,加里脊,加生菜,加培根等等,全凭个人的喜好来,这个过程就是一个装饰器模式。
下面我们用代码还原一下码农的生活。首先创建一个手抓饼的抽象Pancake类:
/*** @author jackxu*/
public abstract class Pancake {protected abstract String getMsg();protected abstract int getPrice();}
创建一个基本的手抓饼类BasePancake,我们把这个叫做标配,就是什么都不加的五块钱一个
/*** @author jackxu*/
public class BasePancake extends Pancake {@Overrideprotected String getMsg() {return "标配手抓饼";}@Overridepublic int getPrice() {return 5;}}
然后再创建一个扩展手抓饼的抽象装饰器PancakeDecorator类:
/*** @author jackxu*/
public class PancakeDecorator extends Pancake {private Pancake pancake;public PancakeDecorator(Pancake pancake) {this.pancake = pancake;}@Overrideprotected String getMsg() {return this.pancake.getMsg();}@Overridepublic int getPrice() {return this.pancake.getPrice();}}
创建一个继承自抽象装饰器类的生菜装饰器LettuceDecorator类:
/*** @author jackxu*/
public class LettuceDecorator extends PancakeDecorator {public LettuceDecorator(Pancake pancake) {super(pancake);}@Overrideprotected String getMsg() {return super.getMsg() + "+1片生菜";}@Overridepublic int getPrice() {return super.getPrice() + 1;}}
同理创建一个鸡蛋装饰器EggDecorator类:
/*** @author jackxu*/
public class EggDecorator extends PancakeDecorator {public EggDecorator(Pancake pancake) {super(pancake);}@Overrideprotected String getMsg() {return super.getMsg() + "+1个鸡蛋";}@Overridepublic int getPrice() {return super.getPrice() + 1;}}
好,现在所有的类都已经写完了,让我们写个测试用例来测试一下:
/*** @author xhj* @date 2021/2/23 16:45*/
public class Test {public static void main(String[] args) {//A同学买了一个标配Pancake pancake = new BasePancake();System.out.println("A同学买了一个" + pancake.getMsg() + ",总价是" + pancake.getPrice() + "元");//B同学买了加鸡蛋的手抓饼Pancake pancakeWithEgg = new EggDecorator(pancake);System.out.println("B同学买了一个" + pancakeWithEgg.getMsg() + ",总价是" + pancakeWithEgg.getPrice() + "元");//C同学买了加生菜的手抓饼Pancake pancakeWithLettuce = new LettuceDecorator(pancake);System.out.println("C同学买了一个" + pancakeWithLettuce.getMsg() + ",总价是" + pancakeWithLettuce.getPrice() + "元");//D同学买了加鸡蛋加生菜的手抓饼Pancake pancakeWithEggAndLettuce = new LettuceDecorator(pancakeWithEgg);System.out.println("D同学买了一个" + pancakeWithEggAndLettuce.getMsg() + ",总价是" + pancakeWithEggAndLettuce.getPrice() + "元");}}
运行结果:
怎样,与我们预期希望看到的结果相符吧,我们用代码还原了现实生活中的一个场景。标配还是那个标配,对于别的需求,我们可以通过层层包装、装饰来实现很多的排列组合,而不是通过继承的方式,为每一种情况都生成一个类,那这样就会产生很多的类,这就是装饰器巧妙、灵活的地方。
最后让我们看下这几个类的UML类图:
和上面通用的类图长的一样吧,这里的PancakeDecorator抽象装饰器是非必需的,如果装饰器多的话我们可以抽象一个出来,如果装饰器单一的话,就可以省略该类,直接继承Pancake实现一个具体装饰器即可。
源码中的应用场景
当我在学习mybatis里面的一级缓存和二级缓存的时候,我看它的源码,发现在cache包下面有一个熟悉的单词,那就是decorators,这个就是装饰的意思,我大胆的猜测它用的就是装饰器模式。
查看了一下引用,发现一段似曾相识的代码,原来decorators包下的每一个类都是装饰类,这里面将cache层层的包装,达到对缓存作用增强的功能。
具体增强的功能如下:
装饰器模式的优缺点
优点:
- 装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果。
- 装饰器完全遵守开闭原则。
缺点: - 会出现更多的代码,更多的类,增加程序复杂性。
- 动态装饰时,多层装饰会更复杂。
源码
https://github.com/xuhaoj/pattern-demo ,其他设计模式的例子也在该项目中,谢谢大家的观看。
手抓饼加生菜加鸡蛋的装饰器模式相关推荐
- 通过装饰器模式为 RoundedBitmapDrawable 加边框
1. 为什么要给 RoundedBitmapDrawable 加边框? 在我们平时生活中,大多数的 App 不光是圆角头像,有很多 App 在圆角头像上还加了一个边框,如: 今天我们就在 <看完 ...
- python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
- python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
- 【设计模式(九)】结构型模式之装饰器模式
个人学习笔记分享,当前能力有限,请勿贬低,菜鸟互学,大佬绕道 如有勘误,欢迎指出和讨论,本文后期也会进行修正和补充 前言 中秋刚过没多久,虽然我这种粗人对月饼无感,但是公司发的肯定得收的嘛 拿回家当零 ...
- 【源码分析设计模式 5】Java I/O系统中的装饰器模式
一.基本介绍 动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 二.装饰器模式的结构 1.Component,抽象构件 Component是一个接口或者抽象类,是定义我们 ...
- 设计模式之装饰器模式(C++实现)
更多设计模式参看: 设计模式之模式概述(模式汇总)(C++实现) 文章目录 介绍 意图: 解决问题: 实现概述: 要点: 应用场景: 优点: 缺点: 模式结构 角色 类图 代码示例 GitHub Co ...
- 设计模式之门面模式与装饰器模式详解和应用
目录 1 门面模式定义 1.1 门面模式的应用场景 1.2 门面模式的通用写法 1.3 门面模式业务场景实例 1.4 门面模式在源码中的应用 1.5 门面模式的优缺点 2 装饰器模式 2.1 装饰器模 ...
- java设计模式之装饰器模式
一.装饰器模式简介 装饰器模式可以动态给一个对象添加一些额外的职责,同时又不改变其结构.就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.这种模式创建了一个装饰 ...
- 装饰器模式与java.io包
为什么80%的码农都做不了架构师?>>> Decorator设计模式是典型的结构型模式(在GOF的那本模式的Bible中将模式分为:1.创建型模式:2.结构型模式:3.行为模式 ...
最新文章
- Linux下查看系统信息
- (JAVA学习笔记) 如何计算2*8效率高(面试题)—— 左移和右移问题。
- wxwidget编译安装_wxWidgets编译安装方法 | 学步园
- PCL中有哪些可用的PointT类型(4)
- AOP(面向切面编程)大概了解一下
- elasticsearch 6.x (四) 单一文档 API 介绍和使用 index和get API
- java channel源码_Netty 4.0 源码分析(三):Channel和ChannelPipeline
- 制作CentOS 5.9自动安装光盘iso镜像
- 傅里叶变换原理讲解及python手动实现
- spark中的广播变量与累加器
- TwinCAT软件部分参数介绍
- 计算机考研408每日一题 day162
- B站视频封面图片获取_CodingPark编程公园
- 电子科大辅助挂课、秒挂(付费)
- 基于opencv的图像阴影消除车辆变道检测
- 【高德地图进阶】--- 带图片的点(3)
- 基于Ubuntu9.10 雨林木风Linux Y1.5发布
- 翻译:SMPL-X模型与SMPLify-X方法
- 【系统架构师】软件架构设计——2需求与质量属性
- 小强升职记思维导图_《小强升职记》思维导图与总结
热门文章
- 老板以为最不可能离职的员工为什么往往会提出离职?
- hadoop启动就出现 WARN util.NativeCodeLoader:... using builtin的解决方法
- H5 CSS适配手机刘海屏高度
- windows下如何用python控制打印机打印_在windows上使用python设置打印机权限
- 21年抓取抖音小姐姐最新版教程!最关键的是无水印下载。这还学不会?
- 华为mate40pro+参数配置
- 英语听力练习的基本法则
- Java:创建方法求两个数的最大值max2,然后再写一个求三个数的最大值max3
- 你就像烟火的美丽,那么美丽
- 猫和老鼠手游怎么才能快速上分?目前胜率已经超过90%