设计模式专题(三)——装饰模式

设计模式专题(三)——装饰模式

(原创内容,转载请注明来源,谢谢)

一、概述

装饰模式(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

相关阅读:

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏web前端教室

大白话 Promise,这到底是干啥用的?

任何东西不可能凭空出来。那么Promise,它到底是个啥?干嘛用的?为解决什么问题而出现的?咱们以这几个问题为线索,简单的说一下。为什么说是简单说一下呢?因为要...

1819
来自专栏程序员的SOD蜜

在SQLMAP中使用动态SQL

最近有几个同事和朋友询问如何在SQLMAP中“拼接字符串”,因为有时候条件的数量不固定,条件参数类型也不固定,无法写出 @参数名 这样的SQL语句,也就是大家常...

2039
来自专栏Aloys的开发之路

C/C++中的abort、atexit、exit和_Exit

     这几个函数都在头文件#include <stdlib.h>中声明。exit、_Exit与abort函数使程序终止,控制并不返回到这些函数的调用者。 e...

1759
来自专栏青玉伏案

ReactiveSwift源码解析(五) SignalProtocol的observe()、Map、Filter延展实现

上篇博客我们对Signal的基本实现以及Signal的面向协议扩展进行了介绍, 详细内容请移步于《Signal中的静态属性静态方法以及面向协议扩展》。并且聊了S...

2487
来自专栏拂晓风起

node.js 标准/错误输出 和 process.exit

1213
来自专栏小白客

PEP 8-Python编码规范整理

本来昨天打算发这个的,结果我一发出去,发现版面乱了,代码都挤到一块一块儿去了,惨不忍睹,所以赶紧删掉了,给大家造成了一定的干扰 点进推文发现: ? 什么鬼呀,浪...

4068
来自专栏LanceToBigData

Jsoup(一)Jsoup详解(官方)

一、Jsoup概述 1.1、简介     jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API...

3055
来自专栏章鱼的慢慢技术路

Go语言相关练习_选择题(3)

如果是值传递的话子函数对map修改不会影响父函数中的map,如果是地址传递则会影响。

783
来自专栏开源优测

[接口测试_B] 14 pytest+requests实战-参数化

上一篇在一个py文件中,写了一堆test_开头的方法,所有数据和用例都在一个py文件中,本篇尝试读取json文件的测试数据,执行用例。

1004
来自专栏青玉伏案

Java编程之委托代理回调、内部类以及匿名内部类回调(闭包回调)

最近一直在看Java的相关东西,因为我们在iOS开发是,无论是Objective-C还是Swift中,经常会用到委托代理回调,以及Block回调或者说是闭包回调...

1689

扫描关注云+社区