- 浏览: 835521 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
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天了坚持为了我的衣衣
身体健康的问题
学习用。
本装饰器设计模式的示例改自《设计模式 - Java语言中的应用》结城 浩著 page 156 - 163
总共6个文件,
一个客户调用示例Main.php
一个顶层抽象类 Display.php
一个直接继承Display的子类,也是最中间的类StringDisplay
一个继承自顶层抽象类的抽象类Border,代表所有外框类
一个继承自Border的边框外框类SideBorder
一个继承自Border的完整外框类FullBorder
类名与文件名无必然关系,当然相同便于理解
附件可下载所有的类。
Main类
Display类
StringDidplay类
Border类
SideBorder类
FullBorder类
运行效果图o-m-g
没错,其实我觉得说模式就是为了表达一种思路,其实只要用点使用例子把思路表达到位了,class怎么写其实读者自己也能想出来
我对模式的理解就是逻辑复杂了,需要把复杂逻辑散布在各个小文件中,而且是用OO的模式。
本装饰器设计模式的示例改自《设计模式 - Java语言中的应用》结城 浩著 page 156 - 163
总共6个文件,
一个客户调用示例Main.php
一个顶层抽象类 Display.php
一个直接继承Display的子类,也是最中间的类StringDisplay
一个继承自顶层抽象类的抽象类Border,代表所有外框类
一个继承自Border的边框外框类SideBorder
一个继承自Border的完整外框类FullBorder
类名与文件名无必然关系,当然相同便于理解
附件可下载所有的类。
Main类
<?php require_once('Display.php'); require_once('StringDisplay.php'); require_once('Border.php'); require_once('SideBorder.php'); require_once('FullBorder.php'); /** * php装饰器设计模式的客户端示例,目的:显示打印字符的装饰功能。会在浏览器输出字符串,被层层包裹 * * 本设计模式的示例改自《设计模式 - Java语言中的应用》结城 浩著 page 156 - 163 * * 读者机器的条件:php5,某个服务器如apache, * 将几个程序放到服务器文档根目录下, * 访问http://127.0.0.1/Main.php即可看到效果 */ class TestDecorator { public static function main() { //打印“Hello,world”,没有任何装饰 $b1 = new StringDisplay('Hello, world.'); //把装饰字符'#'加在b1的左右两边 $b2 = new SideBorder($b1, '#'); //把b2加上装饰外框 $b3 = new FullBorder($b2); //b4在核心的外面加上了多重外框 $b4 = new SideBorder( new FullBorder( new FullBorder( new SideBorder( new FullBorder( new StringDisplay('Hello, world.') ), '*' ) ) ), '/' ); $b1->show(); $b2->show(); $b3->show(); $b4->show(); } } TestDecorator::main(); ?>
Display类
<?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) . "<br />"; } } } ?>
StringDidplay类
<?php /** * 注意此类一定被包裹在核心,和别的类不同,虽然都是继承Display类 * */ class StringDisplay 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; } } } ?>
Border类
<?php /** * 因为外框又有多种,所以把共性抽取出来,形成此抽象类,其中, * 还确定了每个装饰器子类都有的构造方法和属性,通常就是属于共同接口的对象 */ abstract class Border extends Display { protected $display; //注意到:是同一接口的对象,php //不像java能表达出类型,但实际是的 protected function __construct(Display $display)//后面可看到,子类实际可以扩展构造方法 { $this->display = $display; } } ?>
SideBorder类
<?php /** * 在字符两边输出特定字符(由程序外部指定)的外框类, * 通过Border间接继承Display * */ class SideBorder extends Border { private $borderChar; //装饰用的字符,会写到两边 public function __construct(Display $display, $ch)//注意重写了构造方法。 { parent::__construct($display); $this->borderChar = $ch; } public function getColumns() { 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; } } ?>
FullBorder类
<?php /** * 把字符包裹于其中的外框类 * 通过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) { return '+' . $this->makeLine('-', $this->display->getColumns()) . '+'; } elseif ($row == $this->display->getRows() + 1) { return '+' . $this->makeLine('-', $this->display->getColumns()) . '+'; } else { return '|' . $this->display->getRowText($row - 1) . '|'; } } private function makeLine($ch, $count) { $s = ''; for ($i = 0; $i < $count; $i++) { $s .= $ch; } return $s; } } ?>
运行效果图o-m-g
评论
6 楼
chrisyue
2010-03-11
xieye 写道
讲类不直观,讲对象更加直观一些。
一个装饰器对象,他里面有一个装饰器成员,而这个成员本身是对象,里面又有一个成员,如此类推,可以很深。
当最外部对象执行某方法时,会调用其成员的方法,而其中又会调用其里面成员的方法,当然这都要看函数具体的写法!不过示例中的例子是一直调用到了核心子类的方法。
注意到,为了强制所有子类都实现,在顶层抽象类中,故意把这些方法都定义成了抽象方法,这就是原因,作者怕把自己也搞迷糊,所以让编译器来替我们检查(忘了写会页面报错),而方法就是在顶层类中定义抽象方法。
这样讲大家就明白了。^_^
一个装饰器对象,他里面有一个装饰器成员,而这个成员本身是对象,里面又有一个成员,如此类推,可以很深。
当最外部对象执行某方法时,会调用其成员的方法,而其中又会调用其里面成员的方法,当然这都要看函数具体的写法!不过示例中的例子是一直调用到了核心子类的方法。
注意到,为了强制所有子类都实现,在顶层抽象类中,故意把这些方法都定义成了抽象方法,这就是原因,作者怕把自己也搞迷糊,所以让编译器来替我们检查(忘了写会页面报错),而方法就是在顶层类中定义抽象方法。
这样讲大家就明白了。^_^
没错,其实我觉得说模式就是为了表达一种思路,其实只要用点使用例子把思路表达到位了,class怎么写其实读者自己也能想出来
5 楼
xieye
2010-02-02
simon4545 写道
此贴只推荐技术交流,切莫用于实际项目中
我对模式的理解就是逻辑复杂了,需要把复杂逻辑散布在各个小文件中,而且是用OO的模式。
4 楼
simon4545
2010-02-02
此贴只推荐技术交流,切莫用于实际项目中
3 楼
ajonjun
2010-01-19
谢谢,通俗易懂
2 楼
ymdf
2010-01-16
楼主有没其他设计模式的详细解析啊,感觉这方面资料实在太少了
1 楼
xieye
2009-09-13
讲类不直观,讲对象更加直观一些。
一个装饰器对象,他里面有一个装饰器成员,而这个成员本身是对象,里面又有一个成员,如此类推,可以很深。
当最外部对象执行某方法时,会调用其成员的方法,而其中又会调用其里面成员的方法,当然这都要看函数具体的写法!不过示例中的例子是一直调用到了核心子类的方法。
注意到,为了强制所有子类都实现,在顶层抽象类中,故意把这些方法都定义成了抽象方法,这就是原因,作者怕把自己也搞迷糊,所以让编译器来替我们检查(忘了写会页面报错),而方法就是在顶层类中定义抽象方法。
这样讲大家就明白了。^_^
一个装饰器对象,他里面有一个装饰器成员,而这个成员本身是对象,里面又有一个成员,如此类推,可以很深。
当最外部对象执行某方法时,会调用其成员的方法,而其中又会调用其里面成员的方法,当然这都要看函数具体的写法!不过示例中的例子是一直调用到了核心子类的方法。
注意到,为了强制所有子类都实现,在顶层抽象类中,故意把这些方法都定义成了抽象方法,这就是原因,作者怕把自己也搞迷糊,所以让编译器来替我们检查(忘了写会页面报错),而方法就是在顶层类中定义抽象方法。
这样讲大家就明白了。^_^
发表评论
-
召唤神龙 - 安装 centos 8, php 8, mysql 8, laravel 8 的整套 php 运行环境
2020-11-27 16:26 712本文编写时间:2020-11-27 传说集齐龙珠可以召唤神 ... -
centos8 使用阿里镜像快速安装php7.4套件
2020-11-15 00:48 857centos8 使用阿里镜像快速安装php7.4套件 本文只 ... -
centos7 使用阿里镜像快速安装php7.4套件
2020-11-15 00:32 1259本文只考虑centos7 今日 2020-11-16 rem ... -
composer常用命令
2020-11-05 14:46 1483列出当前全局配置 composer config -l -g ... -
期待centos8+php8 + mysql8 + laravel8,8888
2020-10-29 19:24 525期待centos8+php8 + mysql8 目前主要使用 ... -
ubuntu 安装 php7.4以及各类插件
2020-10-24 13:20 1133ubuntu 安装 php7.4以及各类插件 安装系统 最近 ... -
宝塔定义站点
2020-02-24 10:41 2宝塔定义站点。 1111111111111111111111 ... -
让php-fpm以root账号运行
2020-02-19 21:41 827一般来说,我们没有这种需求,但是当需要时, 可以让php-fp ... -
将代码部署到coding.net
2020-01-10 14:20 651coding.net 是一个git仓库,有免费有收费。 首先 ... -
php部署工具deployer技巧 - vendor目录创建
2020-01-06 12:06 914deployer是个好东西,可是每次都composer ,其实 ... -
自定义redis多个实例
2020-01-04 01:17 650假如多个项目部署到同一台服务器,有时会被redis的各项目前缀 ... -
推荐使用php的部署工具 deployer
2020-01-03 16:48 923php部署代码可以使用 https://deployer.or ... -
使用composer 类库 cachetool 清除opcache 的缓存
2020-01-03 16:38 968php的生产服务器上,需要把opche打开。 但有时,会被缓 ... -
laravel容器学习体会
2019-12-31 15:11 678根据文档与实测结果 假设我在app下建一个Services目 ... -
phalcon 自定义超强日志类
2019-12-18 10:00 834phalcon自带的日志文件类,有两个麻烦之处。 1、路径不能 ... -
自定义后台的使用
2019-12-18 05:22 427如果自己写后台,保存用户的表单请求值 所有的情况如下: 1 ... -
phalcon 自定义事件使用的多种方式
2019-12-16 20:43 781方法1:官方文档的方式。 这是控制器: public ... -
phalcon对控制器返回值的使用以输出json
2019-12-16 19:17 836在phalcon里,控制器的Action的方法的返回值没啥用。 ... -
phalcon数据库DB使用实例
2019-12-12 17:12 703整理了一下phalcon的db使用,写了个demo。 ... -
php-redis5.0降级成php-redis4.3
2019-08-22 00:01 896最新版本的php的redis插件,版本是5.0 但是可能会有 ...
相关推荐
书中详细介绍了多种iOS设计模式,包括单例模式、工厂模式、建造者模式、代理模式、装饰器模式、观察者模式、策略模式、状态模式、模版方法模式和访问者模式。每个模式都配有实际的Objective-C代码示例,帮助读者理解...
7. PHP中面向对象编程的其他设计模式和技巧:文中提到了多种面向对象的PHP设计模式和技巧,比如《php面向对象程序设计入门教程》、《PHP基本语法入门教程》等,这些都是学习PHP编程的宝贵资源。 通过对本文的知识点...
### 设计模式总结笔记 #### 一、概述 设计模式是一种在特定上下文中解决软件设计问题的方案。它并不是一种现成的代码片段或者框架,而是一种指导思想,帮助开发者理解如何更好地组织代码来解决问题。设计模式可以...
这个网站可能包含更多的书籍、教程、代码示例和社区支持,对深入学习和交流PHP设计模式非常有帮助。 总的来说,通过学习《PHP设计模式》,开发者能够理解并应用这些模式,提高代码质量,增强代码的可读性和可维护性...
- **组件(Component)**: 定义一个接口,被装饰者和装饰器共同实现。 - **装饰者(Decorator)**: 继承组件接口,包含一个指向组件对象的引用,并可以添加额外的功能。 - **具体装饰者(Concrete Decorator)**:...
本项目名为“design-patterns:PHP中的设计模式示例”,显然是一个用于展示和学习PHP设计模式的资源库。 在PHP中,常见的设计模式可以分为三类:创建型模式、结构型模式和行为型模式。这些模式帮助开发者在面对复杂...
下面,我们将详细探讨这23种设计模式。 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在多线程环境下,单例模式能有效控制资源的使用。 2. **工厂方法模式**:定义一个用于创建对象的接口,让子类...
迭代器模式(Iterator Pattern)是一种行为设计模式,它提供了一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。PHP作为一门面向对象的编程语言,其标准库(SPL)中就内置了对迭代器模式...
PHP常见的设计模式有单例模式、工厂模式、装饰器模式、观察者模式等,这些模式在类库源码中经常被应用,有助于我们构建更稳定、可维护的代码。 在PHP类库中,错误处理是不可或缺的一部分。通常,源码会包含异常处理...
书中涵盖了多种设计模式,如工厂模式、单例模式、观察者模式、装饰器模式、策略模式等。这些模式可以帮助开发者写出灵活、可扩展的代码,并降低代码间的耦合度。 3. 实践与最佳实践: 除了理论知识,书籍还强调...
**PHP OOP与Laravel设计模式实践指南** 在软件开发中,设计模式是解决常见问题的最佳实践和模板,尤其在面向对象编程(OOP)中,它们为代码组织和复用提供了强大的指导。PHP作为流行的服务器端脚本语言,与Laravel...
调解者模式(Mediator Pattern)是一种行为型设计模式,旨在通过引入一个中间组件——调解者,来减少一系列对象之间的通信复杂度。这种模式允许对象之间通过一个中央点进行交互,从而使得这些对象之间不会直接相互...
- **动态选择装饰器**:Sitemesh允许根据特定条件动态选择装饰器,实现更加个性化的布局设计。 - **属性体系**:Sitemesh提供了一套功能丰富的属性体系,支持构建更为复杂和灵活的装饰器,而Struts Tiles在这方面的...
8. **面向对象设计模式**:SOLID原则通常与设计模式结合使用,如工厂模式、单例模式、观察者模式、装饰器模式等,这些模式在项目中可能有所体现。 9. **PHP的类和对象**:包括类的定义、构造函数、析构函数、属性和...
3. **利用设计模式**:使用策略、工厂或装饰者等设计模式,可以使代码更易于理解和维护,同时减少不必要的嵌套。 4. **检查数据流**:确保在处理数据时没有形成循环引用或无限循环。例如,在遍历数组或数据库记录时...
Zend Framework 遵循 Model-View-Controller(MVC)设计模式,提倡“干干净净的代码”原则,使开发者能够快速构建健壮的 Web 应用。它提供了许多组件,如数据库抽象层、缓存、安全、表单处理、文件上传、邮件发送等...
以上知识点在实际开发中具有广泛应用,如在设计模式中,装饰模式、观察者模式和访问者模式都是基于面向对象特性实现的。装饰模式允许动态地给对象添加新的行为或职责;观察者模式用于实现对象间的发布/订阅机制;...
15. 装饰设计模式允许动态地给一个对象添加一些额外的职责,装饰类持有被装饰对象的引用。 16. 在Windows 98中,直接拖动文件或目录到指定位置通常是复制或移动操作,而不是删除。 17. PowerPoint中,设置的项目...
错误控制器示例 7.11. 使用传统的模块目录结构 7.11.1. 简介 7.11.2. 指定模块控制器目录 7.11.3. Routing to modules 7.11.4. 模块或全局缺省控制器 7.12. MVC 异常 7.12.1. 介绍 7.12.2. 如何处理异常? ...