12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式
1、Decorator模式
装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
2、介绍
使用场景: 1、扩展一个类的功能。2、动态增加功能,动态撤销。
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
3、示例代码
示例以:明星和普通人 俩种角色开题,示例演示俩种不同角色的穿衣,以及品牌
定义PersonComponent类
package cn.design.structured.decorator; /**
* @author lin
* @version 1.0
* @date 2020-07-24 17:32
* @Description TODO
*/
public interface PersonComponent { String toDoingDay(); String getRole();
}
定义ConCreatePersonComponent类
package cn.design.structured.decorator; /**
* @author lin
* @version 1.0
* @date 2020-07-24 17:37
* @Description TODO
*/
public class ConCreatePersonComponent implements PersonComponent {
String name;
String role;
String faxing;
/**
* 上装
*/
String jacket;
/**
* 下装
*/
String bottoms;
String shoes; public ConCreatePersonComponent(String name, String role, String faxing, String jacket, String bottoms, String shoes) {
this.name = name;
this.role = role;
this.faxing = faxing;
this.jacket = jacket;
this.bottoms = bottoms;
this.shoes = shoes;
} @Override
public String toDoingDay() {
return "name='" + name + ",role=" + role + ",今天发型faxing=" + faxing + ",上装jacket=" + jacket + ",下装bottoms=" + bottoms + ",鞋子shoes=" + shoes + " 过了一天";
} @Override
public String getRole() {
return role;
} }
定义BaseDecorator类
package cn.design.structured.decorator; /**
* @author lin
* @version 1.0
* @date 2020-07-24 17:40
* @Description TODO
*/
public abstract class BaseDecorator implements PersonComponent {
String decoratorStr;
PersonComponent component; public BaseDecorator(PersonComponent component) {
this.component = component;
} @Override
public String toDoingDay() {
String role = component.getRole(); if (role.equalsIgnoreCase("star")) {
decoratorStr = " today 吃雪糕,骑着自行车 ";
} else {
decoratorStr = " today 吃西餐,开车奔驰 ";
}
String str = component.toDoingDay();
return decoratorStr + ";" + str;
} }
定义ConCreateBaseDecorator类
package cn.design.structured.decorator; /**
* @author lin
* @version 1.0
* @date 2020-07-24 17:49
* @Description TODO
*/
public class ConCreateBaseDecorator extends BaseDecorator { public ConCreateBaseDecorator(PersonComponent component) {
super(component);
} @Override
public String toDoingDay() {
String old = super.toDoingDay();
String role = component.getRole();
if (role.equalsIgnoreCase("star")) {
decoratorStr += ("; ConCreateBaseDecorator 装备升级 周围围着很多小迷妹");
} else {
decoratorStr += ("; ConCreateBaseDecorator 糟糕 被老师叫到了 办公室");
}
return decoratorStr + ";" +
old + ";";
} @Override
public String getRole() {
return null;
} }
定义DecoratorMain测试类
package cn.design.structured.decorator; /**
* @author lin
* @version 1.0
* @date 2020-07-24 17:32
* @Description TODO
*/
public class DecoratorMain {
public static void main(String[] args) {
PersonComponent student = new ConCreatePersonComponent("小明", "student", "平头", "校服", "休闲裤", "老北京拖鞋");
PersonComponent star = new ConCreatePersonComponent("黄晓明", "star", "大背头", "西装", "西裤", "芬迪皮鞋");
// 普通修饰
BaseDecorator b1 = new ConCreateBaseDecorator(student);
System.out.println(b1.toDoingDay());
// 精装修
BaseDecorator b2 = new ConCreateBaseDecorator(star);
System.out.println(b2.toDoingDay());
} }
运行结果如下:
today 吃西餐,开车奔驰 ; ConCreateBaseDecorator 糟糕 被老师叫到了 办公室; today 吃西餐,开车奔驰 ;name='小明,role=student,今天发型faxing=平头,上装jacket=校服,下装bottoms=休闲裤,鞋子shoes=老北京拖鞋 过了一天;
today 吃雪糕,骑着自行车 ; ConCreateBaseDecorator 装备升级 周围围着很多小迷妹; today 吃雪糕,骑着自行车 ;name='黄晓明,role=star,今天发型faxing=大背头,上装jacket=西装,下装bottoms=西裤,鞋子shoes=芬迪皮鞋 过了一天;
4、深入了解
类图:
角色:
◆Component
增加功能时的核心角色。以本章开头的例子来说,装饰前的蛋糕就是Component角色。Component角色只是定义了蛋糕的接口( API)。在示例程序中,由Display类扮演此角色。
◆ConcreteComponent
该角色是实现了Component角色所定义的接口(API)的具体蛋糕。在示例程序中,由StringDisplay类扮演此角色。
◆Decorator (装饰物)
该角色具有与Component角色相同的接口( API)。在它内部保存了被装饰对象一Component角色。Decorator 角色知道自己要装饰的对象。在示例程序中,由Border类扮演此角色。
◆ConcreteDecorator (具体的装饰物)
该角色是具体的Decorator角色。在示例程序中,由SideBorder类和FullBorder类扮演此角色。
公众号:发哥讲
这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。
如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~
● 扫码关注我们
据说看到好文章不推荐的人,服务器容易宕机!
本文版权归发哥讲和博客园共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。
12、Decorator 装饰器 模式 装饰起来美美哒 结构型设计模式的更多相关文章
- 装饰器模式(Decorator Pattern)
装饰器模式 一.什么是装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装 ...
- PHP设计模式之装饰器模式(Decorator)
PHP设计模式之装饰器模式(Decorator) 装饰器模式 装饰器模式允许我们给一个类添加新的功能,而不改变其原有的结构.这种类型的类属于结构类,它是作为现有的类的一个包装 装饰器模式的应用场景 当 ...
- Java设计模式12:装饰器模式
装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
- c#设计模式之装饰器模式(Decorator Pattern)
引子 在面向对象语言中,我们常常会听到这样一句话:组合优于继承.那么该如何去理解这句话呢? 下面我将以游戏装备为模型用简单的代码去展示它 先创建一个装备的抽象类,然后创建刀枪2个具体的业务子类 pub ...
- 装饰器模式(Decorator) C++
装饰器模式是比较常用的一种设计模式,Python中就内置了对于装饰器的支持. 具体来说,装饰器模式是用来给对象增加某些特性或者对被装饰对象进行某些修改. 如上图所示,需要被装饰的对象在最上方,它自身可 ...
- Java IO流以及装饰器模式在其上的运用
流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...
- python设计模式之装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- java设计模式之 装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...
- JAVA设计模式--装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
随机推荐
- Python之爬虫(十七) Scrapy框架中Spiders用法
Spider类定义了如何爬去某个网站,包括爬取的动作以及如何从网页内容中提取结构化的数据,总的来说spider就是定义爬取的动作以及分析某个网页 工作流程分析 以初始的URL初始化Request,并设 ...
- 老司机带你玩转面试(1):缓存中间件 Redis 基础知识以及数据持久化
引言 今天周末,我在家坐着掐指一算,马上又要到一年一度的金九银十招聘季了,国内今年上半年受到 YQ 冲击,金三银四泡汤了,这就直接导致很多今年毕业的同学会和明年毕业的同学一起参加今年下半年的秋招,这个 ...
- 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。他曾在1935~1936年应邀来中国清华大学讲学。 一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,他回答说:我年龄的立方是个4位数。 我年龄的4次方是个6位数。这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。” 请你推算一下,他当时到底有多年轻。 结果只有一个数。
#include<stdio.h>int main(){ int age=1; int san=0; int si=0; int sum=0; while(age>0) { san= ...
- 【一起学系列】之命令模式:封装一个简单Jedis
意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式的诞生 [产品]:开发小哥,来活啦,咱们需要设计一款遥控器,核心功能就 ...
- CentOS 7.0 x86_64官方正式版系统(64位)
下载地址 http://www.xitongzhijia.net/linux/201603/69219.html
- 七牛云如何绑定二次验证码_虚拟MFA_两步验证_谷歌身份验证器?
一般情况下,点账户名——账户设置——安全设置,即可开通两步验证 具体步骤见链接 七牛云如何绑定二次验证码_虚拟MFA_两步验证_谷歌身份验证器? 二次验证码小程序(官网)对比谷歌身份验证器APP ...
- windows系统远程修改密码
1.需求:公司需要短时间.批量修改一些windows系统的管理员密码: 2.准备工作: a.下载软件:链接:https://pan.baidu.com/s/1kV52DqE1_4siPuxS5Mosc ...
- .net 面试题 2020-2-26
2020-2-26 每日几道面试题1. .NET和C#有什么区别答:.NET一般指 .NET FrameWork框架,它是一种平台,一种技术.C#是一种编程语言,可以基于.NET平台的应用. 2.一列 ...
- springboot+quartz以持久化的方式实现定时任务
springboot+queue以持久化的方式实现定时任务 篇幅较长,耐心的人总能得到最后的答案 小生第一次用quartz做定时任务,不足之处多多谅解. 首先 在springboot项目里做定时任务是 ...
- 大家是怎么做APP接口的版本控制的?欢迎进来看看我的方案。升级版的Versioning
背景 APP不同于网站,网站程序一发版,所有用户看到的都是最新的页面.调用最新的接口,没有新老版本一说.APP一旦下载到用户手机上,用户不更新你拿他一点办法都没有,但是随着业务的调整,同一个接口的请求 ...