慕课网----大话PHP设计模式 五(原型模式,装饰器模式,迭代器模式,代理模式)
2016-02-26 11:17
726 查看
16.原型模式
和工厂模式作用类似,都是用来创建对象
与工厂模式的实现不同,原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象,这样就免去了类创建时重复的初始化操作
原型模式适用于大对象的创建。创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可。
原型模式 这个画布是用foreach循环对长和宽进行循环的,所以如果量大的话,初始化一次需要消耗很多的资源。
使用原型模式的情况,尤其有些初始化的时候,比如还要设置颜色,长度等信息,然后用clone的话会减少资源消耗
//使用原型模式的情况,尤其有些初始化的时候,比如还要设置颜色,长度等信息,然后用clone的话会减少资源消耗
17.装饰器模式
可以动态地添加修改类的功能
一个类提供一项功能,如果要在修改并添加额外的功能,传统的编进模式,需要写一个子类来继承他,并重新实现类的方法
使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活度
比如给上面这个画布增加颜色,传统的就是要重新写一个类去继承画布这个类,然后给他写上增加颜色的方法。
这个是装饰器模式,其实就是在所有的类调用之前,再加个before和after,这样方便插入新的功能。
其实yii2里面也有这个功能,就是那些event都会加上一个beforeevent和afterevent
实现方式:
首先针对一个类,给他加上Before和after方法,然后定义一个DrawDecorator这个接口
然后只要就可以创建SizeDrawDecorator或者ColorDrawDecorator等一系列的类来继承上面这个接口,然后实现before和after的方法。
然后再index文件中,实例化Canvas这个类,然后对其进行初始化,然后只要用addDecorator的方法来给这个类添加一个装饰器,然后传入要使用的对象,就能实现了。
18.迭代器模式
在不需要内部实现的前提下,遍历一个聚合对象的内部元素
相比于传统的编辑模式,迭代器模式可以隐藏遍历元素的所需操作。
实现方式,先创建一个类去继承php默认的\Iterator,这个是迭代器。
然后需要实现五个接口current,next,valid,rewind,key
然后就可以再外面直接foreach循环然后就能拿到对应的数据,然后就可以直接操作了
//迭代器模式
19.代理模式
在客户端与实体之间建立一个代理对象(proxy),客户端对实体进行操作全部委派给代理对象,隐藏实体的具体实现细节。
Proxy还可以实现与代理模式分离,部署到另外的服务器,业务代码中通过RPC来委派任务。
主要的应用场景,就是mysql的主从结构,业务代码不需要修改就能进行读写分离。在proxy中对所有读的操作请求主库,然后写的操作请求从库。
传统的实现方式如下:
然后用了代理模式,就需要创建一个Proxy的类,然后在这个类中判断是执行读还是写的操作,然后分别调用不同的库来实现读写分离。
然后再index文件中调用的时候,这样就看不到数据的实际操作,如调用哪个库之类的信息
和工厂模式作用类似,都是用来创建对象
与工厂模式的实现不同,原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象,这样就免去了类创建时重复的初始化操作
原型模式适用于大对象的创建。创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可。
原型模式 这个画布是用foreach循环对长和宽进行循环的,所以如果量大的话,初始化一次需要消耗很多的资源。
使用原型模式的情况,尤其有些初始化的时候,比如还要设置颜色,长度等信息,然后用clone的话会减少资源消耗
//原型模式 这个画布是用foreach循环对长和宽进行循环的,所以如果量大的话,初始化一次需要消耗很多的资源。 //原本的情况是如下的 //$canvas1 = new Imooc\Canvas(); //$canvas1->init(); // //$canvas1->rect(3, 6, 4, 12); //$canvas1->draw(); // //$canvas2 = new Imooc\Canvas(); //$canvas2->init(); // //$canvas2->rect(3, 6, 4, 12); //$canvas2->draw();
//使用原型模式的情况,尤其有些初始化的时候,比如还要设置颜色,长度等信息,然后用clone的话会减少资源消耗
$prototype = new Imooc\Canvas(); $prototype->init(); $canvas1 = clone $prototype; $canvas1->rect(3, 6, 4, 12); $canvas1->draw(); $canvas2 = clone $prototype; $canvas2->rect(3, 6, 4, 12); $canvas2->draw();
17.装饰器模式
可以动态地添加修改类的功能
一个类提供一项功能,如果要在修改并添加额外的功能,传统的编进模式,需要写一个子类来继承他,并重新实现类的方法
使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活度
比如给上面这个画布增加颜色,传统的就是要重新写一个类去继承画布这个类,然后给他写上增加颜色的方法。
这个是装饰器模式,其实就是在所有的类调用之前,再加个before和after,这样方便插入新的功能。
其实yii2里面也有这个功能,就是那些event都会加上一个beforeevent和afterevent
实现方式:
首先针对一个类,给他加上Before和after方法,然后定义一个DrawDecorator这个接口
<?php namespace Imooc; interface DrawDecorator { //这个是装饰器模式,其实就是在所有的类调用之前,再加个before和after,这样方便插入新的功能。 //其实yii2里面也有这个功能,就是那些event都会加上一个beforeevent和afterevent function beforeDraw(); function afterDraw(); }
然后只要就可以创建SizeDrawDecorator或者ColorDrawDecorator等一系列的类来继承上面这个接口,然后实现before和after的方法。
然后再index文件中,实例化Canvas这个类,然后对其进行初始化,然后只要用addDecorator的方法来给这个类添加一个装饰器,然后传入要使用的对象,就能实现了。
//装饰器模式的使用 $canvas1 = new Imooc\Canvas(); $canvas1->init(); $canvas1->addDecorator(new Imooc\ColorDrawDecorator('green')); $canvas1->addDecorator(new Imooc\SizeDrawDecorator('10px')); $canvas1->rect(3, 6, 4, 12); $canvas1->draw();
18.迭代器模式
在不需要内部实现的前提下,遍历一个聚合对象的内部元素
相比于传统的编辑模式,迭代器模式可以隐藏遍历元素的所需操作。
实现方式,先创建一个类去继承php默认的\Iterator,这个是迭代器。
然后需要实现五个接口current,next,valid,rewind,key
<?php namespace IMooc; //\Iterator这个是迭代器,是php默认的 //是个接口,需要实现五个接口current,next,valid,rewind,key class AllUser implements \Iterator { protected $ids; protected $data = array(); protected $index;//迭代器的当前位置 function __construct() { //获取数据库,然后获取所有的id $db = Factory::getDatabase(); $result = $db->query("select id from user"); $this->ids = $result->fetch_all(MYSQLI_ASSOC); } //当前的元素 function current() { $id = $this->ids[$this->index]['id']; return Factory::getUser($id); } //下个元素 function next() { $this->index ++; } //当前是否还有下个元素 function valid() { return $this->index < count($this->ids); } //重置整个迭代器 function rewind() { $this->index = 0; } //在迭代器中的位置 function key() { return $this->index; } }
然后就可以再外面直接foreach循环然后就能拿到对应的数据,然后就可以直接操作了
//迭代器模式
$user = new Imooc\AllUser(); foreach($User as $user){ var_dump($user->name); $user->serial_no = rand(10000, 90000);//修改某个字段成一个随机数 }
19.代理模式
在客户端与实体之间建立一个代理对象(proxy),客户端对实体进行操作全部委派给代理对象,隐藏实体的具体实现细节。
Proxy还可以实现与代理模式分离,部署到另外的服务器,业务代码中通过RPC来委派任务。
主要的应用场景,就是mysql的主从结构,业务代码不需要修改就能进行读写分离。在proxy中对所有读的操作请求主库,然后写的操作请求从库。
传统的实现方式如下:
然后用了代理模式,就需要创建一个Proxy的类,然后在这个类中判断是执行读还是写的操作,然后分别调用不同的库来实现读写分离。
<?php namespace Imooc; class Proxy implements IUserProxy { function getUserName($id) { $db = Factory::getDatabase('slave'); $db->query("select name from user where id =$id limit 1"); } function setUserName($id, $name) { $db = Factory::getDatabase('master'); $db->query("update user set name = $name where id =$id limit 1"); } }
然后再index文件中调用的时候,这样就看不到数据的实际操作,如调用哪个库之类的信息
//代理模式 这样就看不到数据的实际操作,如调用哪个库之类的信息 $proxy = new Imooc\Proxy(); $proxy->getUserName($id); $proxy->setUserName($id, $proxy);
相关文章推荐
- 一个关于if else容易迷惑的问题
- Python动态类型的学习---引用的理解
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- PropertyChangeListener简单理解
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 设计模式之行为型模式 - 调用行为的传递问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- PHP数据库长连接mysql_pconnect的细节
- 浅谈设计模式的学习
- Php Installing An Expansion
- 土人系列AS入门教程 -- 对象篇
- Ruby中的迭代器详解