装饰者模式及php实现
装饰模式(Decorator Pattern) :
动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为“油漆工模式”,它是一种对象结构型模式。
模式动机:
一般有两种方式可以实现给一个类或对象增加行为:
继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。
装饰模式包含如下角色:
Component: 抽象构件
ConcreteComponent: 具体构件
Decorator: 抽象装饰类
ConcreteDecorator: 具体装饰类
UML图:
代码实现:
<?php
header("Content-type:text/html;Charset=utf-8"); //被装饰者基类
interface Component{
function operation();
}
//具体被装饰者类
class ConcreteComponent implements Component{
function operation(){
echo "加了被装饰者";
}
}
//装饰者基类
abstract class Decorator implements Component{
private $component;
function __construct($component){
$this->component = $component;
}
//override
function operation(){
$this->component->operation();
}
}
//具体装饰类A
class ConcreteDecoratorA extends Decorator {
public function __construct(Component $component) {
parent::__construct($component); } public function operation() {
parent::operation();
$this->addedOperationA(); // 新增加的操作
} public function addedOperationA() {
echo ",又加了A个性化装饰<br>";
}
}
//具体装饰类B
class ConcreteDecoratorB extends Decorator {
public function __construct(Component $component) {
parent::__construct($component); } public function operation() {
parent::operation();
$this->addedOperationB(); // 新增加的操作
} public function addedOperationB() {
echo ",又加了B个性化装饰<br><br>";
}
} //测试
$decoratorA = new ConcreteDecoratorA(new ConcreteComponent());
$decoratorA->operation();
$decoratorB = new ConcreteDecoratorB($decoratorA);
$decoratorB->operation();
/*
加了被装饰者,又加了A个性化装饰
加了被装饰者,又加了A个性化装饰
,又加了B个性化装饰
*/
?>
装饰模式的优点:
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”
装饰模式的缺点:
使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
装饰者模式及php实现的更多相关文章
- 装饰者模式 Decoration
1.什么是装饰者模式 动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活.当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列 ...
- JAVA装饰者模式(从现实生活角度理解代码原理)
装饰者模式可以动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 该模式的适用环境为: (1)在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- 设计模式(九)装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- PHP 装饰器模式
装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...
- C#设计模式-装饰者模式
在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).Access ...
- Java 的设计模式之一装饰者模式
刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...
- 《Head First 设计模式》之装饰者模式
作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5922248.html 模式名称 装饰者模式(Decorator Pattern) 需求 定义咖啡厅中的 ...
- DecoratorPattern(装饰器模式)
/** * 装饰者模式 * @author TMAC-J * 总的来说,装饰者模式就是继承的应用 */ public class DecoratorPattern { interface Beans{ ...
- 设计模式-装饰器模式(Decrator Model)
文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...
随机推荐
- Ubuntu 重启命令
重启命令: 1.直接reboot 2.shutdown -r now 这两种都是立刻重启 3.shutdown -r 大概30秒后会重启 关机命令:1.halt 立刻关机2.poweroff 立刻 ...
- 五 Vue学习 首页学习 (上)
首页: http://localhost:8002/#/, 登录页面如下: index.js文件中如下的路由配置,转过去看login.vue是如何实现的. const routes = [ { ...
- 《Java多线程编程核心技术》读后感(十七)
使线程具有有序性 正常情况下,线程在运行时多个线程之间执行任务的时机时无序的.可以通过改造代码的方式使它们运行具有有序性 package Seven; public class MyThread ex ...
- 鼠标右键添加cmd
给鼠标右键添加 cmd https://jingyan.baidu.com/article/3f16e003c408142591c103b2.html 有一些软件,最好不要装到Program File ...
- 永恒之蓝(EternalBlue)MS17-010
附加知识: 漏洞来源与背景: 这个漏洞最初是由NSA(美国国家安全局)发现的,但是他们发现漏洞他不讲,然后遭殃了吧. 后来 有一个黑客组织叫:Shadow Brokers (影子经纪人) 入侵了NSA ...
- shell程序---编译目录下全部.c或.cpp文件
今天大波又提起昨天我说的那个程序.这样的,起初我想写一个makefile,每次写完新代码后一键编译目录下所有的.cpp文件. 原因是用makefile的话,每次要把目标文件加紧去才能编译.感觉不方便. ...
- HDU 1512 Monkey King (左偏树+并查集)
题意:在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识 (认识具有传递性)的两只猴子之间.争斗时,两只猴子都 ...
- 将Angular6自己定义的模块发布成npm包
创建自己的模块组件 1. ng new 一个工程 2. ng g m 创建模块 例如我这里的modules文件下创建header模块 3. ng g c modules/head 创建一个hear组件 ...
- UOJ #32. 【UR #2】跳蚤公路【Floydbellman-ford】
首先看这个范围很夸张但是其实有限制的也就在1e18*n范围里(走完一圈的边权),然后限制一定是有负环 用Floyd传递闭包,然后设f[i][j][k]为从1走了i步到j并且有k个x的最短路,用B-F处 ...
- 洛谷P2759 奇怪的函数
P2759 奇怪的函数 题目描述 使得 x^x 达到或超过 n 位数字的最小正整数 x 是多少? 输入输出格式 输入格式: 一个正整数 n 输出格式: 使得 x^x 达到 n 位数字的最小正整数 x ...