- 浏览: 829010 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
xieye:
jetty插件有好几个版本,1.6,1.7,1.8
我选的是用 ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
还有,
注:第2部分时,需要先安装jetty,我自己在安装过程 ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
说明一下:实际使用中,导入时我并没有错误。2、我把eclips ...
tapestry入门(翻译)3 导入项目到eclipse -
xieye:
其实还是有一些先决条件的。1是外部环境,2是进步是阶段性的(意 ...
(转载文章)如何愉悦起来:一位精神治疗师的见解 -
mandy_yanzi:
我都已经饿7天了坚持为了我的衣衣
身体健康的问题
我的设计模式系列文章
php设计模式(1)-- 观察者模式 -- spl标准写法
php设计模式(2)-- 观察者模式 -- 用trait来改进的写法
php设计模式(3)-- 责任链(职责链)模式
php设计模式(4)-- 装饰器模式
分析
网上的套话就不说了。
图片来自红黑联盟:
上图中,Componet 对应我这里的 Display
ConcreteComponet 对应我这里的 BasicDisplay
Decorator 对应我这里的 Border
剩下两个分别对应 FullBorder 和 SiderBorder
装饰器适用场合:假设一个对象有某种功能,在有些时候,需要对这功能增强,但有些时候,又需要使用原有功能。这时使用装饰器。
装饰器和责任链都会有一个长长的对象关联链条,其差异是:责任链强调对同一个消息的不同处理,而不是功能增强。责任链是多个功能,而装饰器是一个功能,但是这个功能有时需要一些小改变,改来改去是同一个功能。
java的流使用了装饰器,说明装饰器也可以改变结果的表现形式,总之,功能增强是个泛泛而言的事情,能做到事情很多。
注意:和观察者,以及责任链一样,类与类的具体哪个和哪个关联,先后顺序等,都放在客户端代码里!
现在我们构造需求。
假设,我们有一个文档,需要打印机打印出来,但是我们希望打印一些边框,让文档漂亮些,边框跟文档内容没关系。但是同一个功能:打印。所以我们使用装饰器。
代码实现
结果展示,非常精巧
php设计模式(1)-- 观察者模式 -- spl标准写法
php设计模式(2)-- 观察者模式 -- 用trait来改进的写法
php设计模式(3)-- 责任链(职责链)模式
php设计模式(4)-- 装饰器模式
分析
网上的套话就不说了。
图片来自红黑联盟:
上图中,Componet 对应我这里的 Display
ConcreteComponet 对应我这里的 BasicDisplay
Decorator 对应我这里的 Border
剩下两个分别对应 FullBorder 和 SiderBorder
装饰器适用场合:假设一个对象有某种功能,在有些时候,需要对这功能增强,但有些时候,又需要使用原有功能。这时使用装饰器。
装饰器和责任链都会有一个长长的对象关联链条,其差异是:责任链强调对同一个消息的不同处理,而不是功能增强。责任链是多个功能,而装饰器是一个功能,但是这个功能有时需要一些小改变,改来改去是同一个功能。
java的流使用了装饰器,说明装饰器也可以改变结果的表现形式,总之,功能增强是个泛泛而言的事情,能做到事情很多。
注意:和观察者,以及责任链一样,类与类的具体哪个和哪个关联,先后顺序等,都放在客户端代码里!
现在我们构造需求。
假设,我们有一个文档,需要打印机打印出来,但是我们希望打印一些边框,让文档漂亮些,边框跟文档内容没关系。但是同一个功能:打印。所以我们使用装饰器。
代码实现
<?php /** * 装饰器模式学习代码。 * * 位于最顶层,表示了整个设计模式示例的功能:打印字符串 * * 这个程序也可以包装多行的文本,只是代码改得复杂一些,不利于看清设计模式。 */ abstract class Display { public abstract function getColumns(); //取得横向的字数,把责任委托给子类,所以抽象,下同 //观察子类可知,只要有一个类使用到了, //需要所有的类都要有这个方法! public abstract function getRows(); //取得纵向的行数,把责任委托给子类 public abstract function getRowText($row);//取得第row行的字符串 public function show() { //因为这个方法的实现是固定的,所以写这里 for ($i = 0; $i < $this->getRows(); $i++) { echo $this->getRowText($i) . PHP_EOL; } echo PHP_EOL; } } /** * 注意此类一定被包裹在核心,和别的类不同,虽然都是继承Display类 * 所以我取名basic */ class BasicDisplay extends Display { private $string; //最里面的,一定会被打印出的字符串 public function __construct($string) { //需要在外部指定 $this->string = $string; } public function getColumns() { //注意!,仅被某类调用,却写到每个类中!! return strlen($this->string); } public function getRows() { //核心只打印一行 return 1; } public function getRowText($row) { //仅在row为0时才返回 if ($row == 0) { return $this->string; } else { return null; } } } /** * 因为外框又有多种,所以把共性抽取出来,形成此抽象类,其中, * 还确定了每个装饰器子类都有的构造方法和属性,通常就是属于共同接口的对象 */ abstract class Border extends Display { protected $display; //注意到:是同一接口的对象,php //不像java能表达出类型,但实际是的 protected function __construct(Display $display) { //后面可看到,子类实际可以扩展构造方法 $this->display = $display; } } /** * 在字符两边输出特定字符(由程序外部指定)的外框类, * 通过Border间接继承Display * */ class SideBorder extends Border { //装饰用的字符,会写到两边 private $borderChar; public function __construct(Display $display, $ch) {//注意重写了构造方法。 parent::__construct($display); $this->borderChar = $ch; } public function getColumns() {// 左右各加一个字符,所以宽度加2 return 1+ $this->display->getColumns() + 1; } public function getRows() { return $this->display->getRows(); } /** * 最后的显示效果如 |hello, world| * 其中两边的|只是示例,由外部传入的。 * 根据php的类型,没有字符类,所以请确保只传入一个字符。这里没有判断,也可以抛异常等。 */ public function getRowText($row) { // 注意这其实在一个循环里,只是每行做同样的处理罢了。 return $this->borderChar . $this->display->getRowText($row) . $this->borderChar; } } /** * 把字符包裹于其中的外框类 * 通过Border间接继承Display * */ class FullBorder extends Border { private $borderChar; public function __construct(Display $display) { parent::__construct($display); } //这些方法很重要,保证了上下的字符对齐(假定字符宽度相等) //注意到:虽然别的类的该方法似乎没有用到, //实际在这里用到了,让本类可以知道里面内核的字符宽度 public function getColumns() { return 1 + $this->display->getColumns() + 1; } public function getRows() { return 1 + $this->display->getRows() + 1; } /** * 把行数确定为核心内容加2后,见上getRows,就可以在顶部和底部输出装饰 * +-------------------+ * +-------------------+ * * 然后,在内容的两边输出 | 字符 */ public function getRowText($row) { if ($row == 0) { // 第1行 return '+' . $this->makeLine('-', $this->display->getColumns()) . '+'; } elseif ($row == $this->display->getRows() + 1) { // 最后一行,= 原有总行数 + 1,因为行数从1算,row从0算。 return '+' . $this->makeLine('-', $this->display->getColumns()) . '+'; } else { return '|' . $this->display->getRowText($row - 1) . '|';//-1 是因为有一个错位,多了一行 } } private function makeLine($ch, $count) { $s = ''; for ($i = 0; $i < $count; $i++) { $s .= $ch; } return $s; } } //打印“Hello,world”,没有任何装饰 $b1 = new BasicDisplay('Hello, world.'); $b1->show(); //把装饰字符'#'加在b1的左右两边 $b2 = new SideBorder($b1, '#'); $b2->show(); //把b2加上装饰外框 $b3 = new FullBorder($b2); $b3->show(); //b4在核心的外面加上了多重外框,请仔细观察图形与每个装饰器的对应关系,很有意思的。 $b4 = new SideBorder( new FullBorder( new FullBorder( new SideBorder( new FullBorder( new BasicDisplay('Hello, world.') ), '*' ) ) ), '/' ); $b4->show();
结果展示,非常精巧
Hello, world. #Hello, world.# +---------------+ |#Hello, world.#| +---------------+ /+-------------------+/ /|+-----------------+|/ /||*+-------------+*||/ /||*|Hello, world.|*||/ /||*+-------------+*||/ /|+-----------------+|/ /+-------------------+/
发表评论
-
召唤神龙 - 安装 centos 8, php 8, mysql 8, laravel 8 的整套 php 运行环境
2020-11-27 16:26 665本文编写时间:2020-11-27 传说集齐龙珠可以召唤神 ... -
centos8 使用阿里镜像快速安装php7.4套件
2020-11-15 00:48 797centos8 使用阿里镜像快速安装php7.4套件 本文只 ... -
centos7 使用阿里镜像快速安装php7.4套件
2020-11-15 00:32 1195本文只考虑centos7 今日 2020-11-16 rem ... -
composer常用命令
2020-11-05 14:46 1422列出当前全局配置 composer config -l -g ... -
期待centos8+php8 + mysql8 + laravel8,8888
2020-10-29 19:24 477期待centos8+php8 + mysql8 目前主要使用 ... -
ubuntu 安装 php7.4以及各类插件
2020-10-24 13:20 1069ubuntu 安装 php7.4以及各类插件 安装系统 最近 ... -
宝塔定义站点
2020-02-24 10:41 2宝塔定义站点。 1111111111111111111111 ... -
让php-fpm以root账号运行
2020-02-19 21:41 806一般来说,我们没有这种需求,但是当需要时, 可以让php-fp ... -
将代码部署到coding.net
2020-01-10 14:20 625coding.net 是一个git仓库,有免费有收费。 首先 ... -
php部署工具deployer技巧 - vendor目录创建
2020-01-06 12:06 882deployer是个好东西,可是每次都composer ,其实 ... -
自定义redis多个实例
2020-01-04 01:17 642假如多个项目部署到同一台服务器,有时会被redis的各项目前缀 ... -
推荐使用php的部署工具 deployer
2020-01-03 16:48 876php部署代码可以使用 https://deployer.or ... -
使用composer 类库 cachetool 清除opcache 的缓存
2020-01-03 16:38 956php的生产服务器上,需要把opche打开。 但有时,会被缓 ... -
laravel容器学习体会
2019-12-31 15:11 647根据文档与实测结果 假设我在app下建一个Services目 ... -
phalcon 自定义超强日志类
2019-12-18 10:00 819phalcon自带的日志文件类,有两个麻烦之处。 1、路径不能 ... -
自定义后台的使用
2019-12-18 05:22 414如果自己写后台,保存用户的表单请求值 所有的情况如下: 1 ... -
phalcon 自定义事件使用的多种方式
2019-12-16 20:43 774方法1:官方文档的方式。 这是控制器: public ... -
phalcon对控制器返回值的使用以输出json
2019-12-16 19:17 812在phalcon里,控制器的Action的方法的返回值没啥用。 ... -
phalcon数据库DB使用实例
2019-12-12 17:12 690整理了一下phalcon的db使用,写了个demo。 ... -
php-redis5.0降级成php-redis4.3
2019-08-22 00:01 884最新版本的php的redis插件,版本是5.0 但是可能会有 ...
相关推荐
这些设计模式不仅在PHP中适用,也是跨语言的编程思想,可以帮助开发者编写出更加高效、可维护和可扩展的代码。在实际项目中,合理运用设计模式,可以使代码结构更加清晰,降低复杂性,提升代码质量。
4. **易于维护**:由于装饰者模式遵循单一职责原则,每个装饰器只负责增加特定的行为,所以代码更容易理解和维护。 在PHP5的项目中,装饰者模式常用于处理如日志记录、缓存管理、权限控制等场景,提供了一种优雅的...
4. **具体装饰器**:实现了装饰器接口的类,持有对组件的引用,并在需要的地方添加额外的行为。装饰者可以叠加,创建更复杂的功能。 ```php class Decorator implements Component { protected $component; ...
装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...
4. 装饰器模式:动态地给一个对象添加额外的功能,而不影响其原有的结构。在PHP中,装饰器模式常用于类的功能扩展,如增加日志记录、性能统计等功能,而不会改变原有类的行为。 5. 适配器模式:使两个不兼容的接口...
2. **装饰器模式(Decorator)**:动态地给对象添加一些额外的职责,可以独立增加功能,不会破坏封装性。 3. **代理模式(Proxy)**:为其他对象提供一种代理以控制对这个对象的访问。 4. **桥接模式(Bridge)**:...
装饰器模式是23种经典设计模式中的一种结构型模式,它允许动态地给一个对象添加额外的职责,就像给一个礼物进行包装一样,可以在不改变其自身的情况下,为其增加新的功能或行为。 在PHP中,装饰器模式的实现通常...
装饰器模式允许在运行时给对象添加新的行为或责任,而无需修改原来的代码。在PHP中,它可以用于动态地扩展类的功能,如增加日志记录或性能统计。 8. **适配器模式(Adapter)** 适配器模式使两个不兼容的接口能够...
《PHP设计模式》是一本探讨如何在PHP编程中应用设计模式的书籍。设计模式是软件工程领域中,解决常见问题的模板或策略。本书作者是美国的Aaron Saray,内容详尽地介绍了各种设计模式,旨在帮助PHP开发者构建出更加...
《PHP设计模式介绍》导言 《PHP设计模式介绍》第一章 编程惯用法 《PHP设计模式介绍》第二章 值对象模式 《PHP设计模式介绍》第...《PHP设计模式介绍》第十二章 装饰器模式 《PHP设计模式介绍》第十三章 适配器模式
7. **装饰器模式**:装饰器模式允许动态地给一个对象添加一些新的行为或职责。通过使用附加的对象,装饰器模式可以在不修改原有代码的情况下扩展功能。 8. **代理模式**:代理模式为其他对象提供一种代理以控制对这...
5. **装饰器模式(Decorator)**:动态地给一个对象添加一些额外的职责。在PHP中,装饰器模式常用于扩展或修改对象的功能,而无需更改其原有的代码。 6. **适配器模式(Adapter)**:使两个不兼容的接口能够协同...
根据提供的文件信息,本文将对《Learning_PHP设计模式》这一主题进行深入解析,重点围绕PHP设计模式的基础概念、分类及应用场景展开讨论。 ### PHP设计模式基础 #### 1. 设计模式简介 设计模式是在软件工程领域内...
因此,我会根据【标题】和【描述】字段中提供的信息,来生成关于PHP设计模式的知识点。 PHP设计模式的知识点主要包括: 1. 设计模式的概念:设计模式是软件开发中用于解决特定问题的一般性模板,它不是直接的代码...
2. 结构型模式:如代理模式(Proxy)、装饰器模式(Decorator)、适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)和享元模式(Flyweight)。这些模式关注如何组织类和对象,...
7. 装饰器模式:装饰器模式动态地给对象添加一些额外的职责,可以用来扩展类的功能,同时保持接口不变。在PHP中,装饰器模式常用于添加日志、性能监控等功能。 8. 组合模式:组合模式允许你将对象组合成树形结构来...
4. 装饰器模式:动态地给对象添加一些额外的职责,可以独立增加功能而不影响其他对象。 5. 代理模式:为其他对象提供一种代理以控制对这个对象的访问,常用于控制访问权限或者延迟加载。 6. 建造者模式:将复杂...
在软件开发中,设计模式是解决常见问题的模板或最佳实践,它们被广泛应用于各种编程语言,包括PHP。本资源“用PHP语言实现16个设计模式.zip”提供了关于如何在PHP环境中应用这些模式的详细指导。以下是这16个设计...
《PHP设计模式-中英双语》是一本深入探讨PHP编程中设计模式的指南,旨在帮助开发者提升代码质量和可维护性。设计模式是软件工程中经过时间验证的、解决常见问题的最佳实践,它们为复杂的软件设计提供了通用解决方案...