设计模式 - 装饰器模式(Decorator)
简介
场景
通过继承和关联都可以给对象增加行为,区别如下:
- 继承是静态的(无法在程序运行时动态扩展),且作用于所有子类。硬编码,高耦合。
- 通过装饰器可以在运行时添加行为和属性到指定对象。关联关系就是在一个类中嵌入另一个类的对象,被嵌入的对象就是装饰器。可以动态决定是否调用这个内嵌对象,低耦合。
模式定义
装饰模式:动态地给指定对象增加额外职责。
装饰模式对客户透明,可以嵌套执行多次装饰,顺序不影响结果。
就增加对象功能来说,装饰模式(关联关系)比继承和实现这两种关系更为灵活。
模式特点
装饰模式包含 4 种角色:
- Component:抽象构件
- ConcreteComponent:具体构件
- Decorator:抽象装饰类
- ConcreteDecorator:具体装饰类
优缺点
优点:
- 装饰模式可以动态扩展一个对象的功能,可以在运行时通过配置文件选择不同的装饰器,从而实现不同的行为
- 装饰类可以排列组合,创造出很多不同行为的组合
- 装饰类扩展时,原有代码无须改变,符合“开闭原则”
缺点:
- 使用装饰模式进行系统设计时将产生很多小对象,每个对象仅负责一部分装饰任务
- 多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐
PHP 代码示例
下面例子中,通过不同的装饰器类对标题进行不同的操作:
<?php
class Book {
private $title;
private $author;
public function __construct($title, $author) {
$this->title = $title;
$this->author = $author;
}
public function getTitle() {
return $this->title;
}
}
class TitleDecorator {
protected $book;
protected $title;
public function __construct(Book $book) {
$this->book = $book;
$this->resetTitle();
}
public function resetTitle() {
$this->title = $this->book->getTitle();
}
public function showTitle() {
return $this->title;
}
}
class TitleStarDecorator extends TitleDecorator {
private $titleDecorator;
public function __construct(TitleDecorator $td) {
$this->titleDecorator = $td;
}
public function starTitle() {
$this->titleDecorator->title = str_replace(" ","*",$this->titleDecorator->title);
}
}
class TitleQuoteDecorator extends TitleDecorator {
private $titleDecorator;
public function __construct(TitleDecorator $td) {
$this->titleDecorator = $td;
}
public function quoteTitle() {
$this->titleDecorator->title = "《".$this->titleDecorator->title."》";
}
}
$book = new Book("a good world", "Lu Xun");
$td = new TitleDecorator($book);
$tsd = new TitleStarDecorator($td);
$tqd = new TitleQuoteDecorator($td);
function write_ln($str) {
echo $str.PHP_EOL.'<br/>';
}
write_ln($book->getTitle());
$tsd->starTitle();
write_ln($td->showTitle());
$tqd->quoteTitle();
write_ln($td->showTitle());
$tqd->quoteTitle();
write_ln($td->showTitle());
输出如下:
a good world
a*good*world
《a*good*world》
《《a*good*world》》
设计模式 - 装饰器模式(Decorator)的更多相关文章
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
- 说说设计模式~装饰器模式(Decorator)
返回目录 装饰器模式,也叫又叫装饰者模式,顾名思义,将一个对象进行包裹,包装,让它变成一个比较满意的对象,这种模式在我们平时项目开发中,经常会用到,事实上,它是处理问题的一种技巧,也很好的扩展了程序, ...
- 设计模式(八)装饰器模式Decorator(结构型)
设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...
- 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)
<?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...
- JAVA设计模式--装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- 装饰器模式-Decorator(Java实现)
装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...
- 装饰器模式 Decorator 结构型 设计模式 (十)
引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼, 加个培根, 加个鸡蛋,多少钱?" 这句话会不 ...
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
- python 设计模式之装饰器模式 Decorator Pattern
#写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...
随机推荐
- BAT程序员常用的开发工具,建议收藏!
今天给大家推荐一批 BAT 公司常用的开发工具,个个好用,建议转发+收藏. 阿里篇 一.Java 线上诊断工具 Arthas Arthas 是阿里巴巴 2018 年 9 月开源的一款 Java 线上诊 ...
- java_第一年_JavaWeb(12)
SimpleTag标签 定义了五个方法:setJspContext.setJspBody.setParent和getParent以及最重要的doTag方法(完成了所有的业务逻辑): setJspCon ...
- 一篇包含了react所有基本点的文章
去年,我写了一本关于学习React.js的小书,原来是大约100页. 今年我要挑战自己,把它归纳为一篇文章. 本文不会涵盖什么是React,或者为什么要学习它. 相反,这是面向已经熟悉JavaScri ...
- Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation
原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...
- 省流量 转:http://www.wtoutiao.com/p/T3b8it.html
前言:“客户端上传时间戳”的玩法,你玩过么?一起聊聊时间戳的奇技淫巧! 缘起:无线时代,流量敏感.APP在登录后,往往要向服务器同步非常多的数据,很费流量,技术上有没有节省流量的方法呢?这是本文要讨论 ...
- 6个优秀的微信小程序ui组件库
开发微信小程序的过程中,选择一款好用的组件库,可以达到事半功倍的效果.自从微信小程序面世以来,不断有一些开源组件库出来,下面6款就是排名比较靠前,用户使用量与关注度比较高的小程序UI组件库.还没用到它 ...
- 升级docker至最新版本
升级docker至最新版本 1.查找主机上关于Docker的软件包 [root@pre1 ~]# rpm -qa | grep docker docker-1.13.1-88.git07f3374.e ...
- python面向对象--类的内置函数
#isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...
- xcopy忽略文件 7zip打包
xcopy src target /Y /r /d /k /f /s /exclude:%cd%\xcopy.config xcopy.config\assets\\tet\ 7z.exe a -tz ...
- Linux 部署或升级openssh7.5p1
运维Linux系统,部署或升级openssh是经常面临的事,以下已redhat6和redhat7为例. 在redhat6中部署openssh会有什么坑,在编辑openssh源码包时会报一些类似的错误, ...