设计模式专题(三)——装饰模式
设计模式专题(三)——装饰模式
(原创内容,转载请注明来源,谢谢)
一、概述
装饰模式(Decorator)是指动态的给一个对象添加额外的职责,就增加功能来说,装饰模式比生成子类更灵活。且装饰模式会将需要的功能按正确的顺序串联起来控制。装饰模式主要由几部份组成。
1)Component抽象类,定义一个装饰方法,继承这个抽象类的类都需要实现装饰方法decorate()。
2)ConcreteComponent类,继承component,是具体装饰方法实现的类。由该类实现将各种装饰的方式组合起来。
3)Decorator抽象类,继承component,其实现装饰方法是通过传入一个Component类型的对象,并执行其自身的decorate方法。
4)ConcreteDecorator类,继承Decorator,起到给component添加职责的功能,即具体某一方面装饰的功能。
二、功能
1)装饰模式是为已有的功能动态的添加更多功能的一种方式。
2)装饰模式把每个要要装饰的功能放在单独的类中,让这个类包装它所要装饰的对象。当要执行特殊行为时,客户端可以在运行时根据需要有选择的、按顺序的包装对象。
3)把类中的功能从类中搬出,简化原有的类。有效的把核心职责和装饰功能分开,去除重复的装饰逻辑。
三、场景
当要给一个类添加若干功能,这些功能之间互不相干,如果仅仅采用继承,当需要加载十几个功能,就需要十几重的继承,这样代码没法维护。当需要修改一个内容,会影响到非常多的类。
此时,就需要用到装饰者模式,让这些添加的内容类都继承同一个父类,而这个父类又和原先待添加的类共同继承一个类,这样便于互相之间的调用。
四、UML类图如下
五、实现
1、设计场景
现设计数据处理类,有一个字符串和一个数组,字符串和数组分别需要经过选择一种方式格式转换、选择一种方式加密。
因此,需要定义如下几个类:
1)数据处理抽象类(DataDealer类形如上图的component类)
2)数据处理实现类(DataDealerConcrete类形如上图的concretecomponent类)
3)数据处理装饰类(DataDecorator类形如上图的decorator类)
4)数据处理具体装饰类(TypeExchange、TransType类形如上图concretedecoratorA、B类)
2、PHP实现如下
<?php
//实现装饰模式,场景:数据处理
/*
现设计数据处理类,有一个字符串和一个数组,
字符串和数组分别需要经过选择一种方式格式转换、选择一种方式加密
因此,需要定义如下几个类:
1)数据处理抽象类(DataDealer类)
2)数据处理实现类(DataDealerConcrete类)
3)数据处理装饰类(DataDecorator类)
4)数据处理具体装饰类(TypeExchange、TransType类)
*/
//数据处理抽象类
abstract class DataDealer{
private $method;//数据处理方法
public functiondeal(){}
}
//数据处理装饰类
abstract class DataDecorator extends DataDealer{
private$dealIns;//datadealer的实例
private $method;//数据处理方法
public function__construct(DataDealer $dealIns, $method){
$this->dealIns= $dealIns;
$this->method= $method;
}
public functiondeal(){
$data =$this->dealIns->deal();
}
}
//数据处理具体类A——格式转换
class TypeExchange extends DataDecorator{
private$dealIns;//datadealer的实例
private $method;//数据处理方法
public function__construct(DataDealer $dealIns, $method){
$this->dealIns= $dealIns;
$this->method= $method;
}
public functiondeal(){
$data = $this->dealIns->deal();
switch($this->method){
case'array2string'://数组转字符串
$data= $this->array2string($data);
break;
case'string2array'://字符串转数组
$data= $this->string2array($data);
break;
default:
break;
}
return$data;
}
private functionstring2array($data){}
private functionarray2string($data){
if(!is_array($data)){
return$data;
}
$str = '';
foreach($dataas $item){
if(is_array($item)){
$str.= $this->array2string($data);
}else{
$str.= $item . '|';
}
}
return $str;
}
}
//数据处理具体类B——序列化方式用于传输
class TransType extends DataDecorator{
private$dealIns;//datadealer的实例
private $method;//数据处理方法
public function__construct(DataDealer $dealIns, $method){
$this->dealIns= $dealIns;
$this->method= $method;
}
public functiondeal(){
$data = $this->dealIns->deal();
switch($this->method){
case'enjson'://json
$data= $this->enJson($data);
break;
case'enseria'://serialize
$data= $this->enSeria($data);
break;
default:
break;
}
return$data;
}
private functionenJson($data){
returnjson_encode($data);
}
private functionenSeria($data){
returnserialize($data);
}
}
//数据处理实现类
class DataDealerConcrete extends DataDealer{
private $data;
public function__construct($data){
$this->data= $data;
}
public functiondeal(){
return$this->data;
}
}
//客户端,调用上述功能实现数据处理
$dataDealerString = new DataDealerConcrete('abcdefg');
$typeExchangeString = new TypeExchange($dataDealerString, 'none');
$transTypeString = new TransType($typeExchangeString, 'enjson');
var_dump($transTypeString->deal('abcdefg'));
$dataDealerArray = new DataDealerConcrete(array('a', 'b', 'c','d'));
$typeExchangeArray = new TypeExchange($dataDealerArray,'array2string');
$transTypeArray = new TransType($typeExchangeArray, 'enseria');
var_dump($transTypeArray->deal(array('a', 'b', 'c', 'd')));
——written by linhxx 217.07.28
相关阅读:
设计模式专题(二)——策略模式
设计模式专题(一)——面向对象的设计原则
- 每周学点大数据 | No.9递归——以阶乘为例
- appium+python自动化24-滑动方法封装(swipe)
- libvirt-虚拟机qos控制
- 【深度】Deep Visualization:可视化并理解CNN
- Appium+python自动化28-name定位
- Appium+python自动化29-toast消息
- guestfs这么强大你知道吗
- appium+python自动化30-list定位(find_elements)
- python笔记4-遍历文件夹目录os.walk()
- 【专知国庆特刊-PyTorch手把手深度学习教程系列01】一文带你入门优雅的PyTorch
- python接口自动化14-multipart/form-data上传图片
- 【干货】RL-GAN For NLP: 强化学习在生成对抗网络文本生成中扮演的角色
- python接口自动化15-multipart/form-data表单提交
- appium+python自动化32-android_uiautomator定位进阶版
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- hiveServer2服务端安装
- hive数据加载
- Python 技术篇-使用opencv读取图片实例演示,python安装opencv库
- 关于页更改并加入一些在线服务
- Hadoop-2.6.0为基础的Hive安装
- Python 技术篇-opencv读取中文路径图片报错及解决办法
- Javaweb鼠标事件案例分析—鼠标移入移出表格颜色变化
- docker registry V2私有仓库搭建
- Python 路径问题:cv2.error: OpenCV(4.1.0)...size.width>0 && size.height>0 in function 'cv::imshow'. 原因与解决
- 算法案例分析—字符串模式匹配算法
- Docker-软件工程集装箱技术
- PyQt5 技术篇-获取电脑屏幕桌面的宽、高和分辨率
- 使用Python快速抠图
- 值得白嫖的数据库常用操作语句汇总(数据库、数据表、数据操作)
- JavaScript 技术篇-js正则表达式匹配字符串左右两边是否包含空格