最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
PHP设计模式实例学习笔记
时间:2014-01-21 编辑:简简单单 来源:一聚教程网
一、值对象模式
再说设计模式-值对象模式之前,你要了解值传递和引用传递:
1.值对象模式概念:
如果你把同一个对象资源赋值给两个不同的变量,然后改变其中的一个变量,另一个变量仍然不受影响。这就是使用值对象模式的目的。
看下面例子:
代码如下 | 复制代码 |
class BadDollar { protected $amount; public function __construct($amount=0) { $this->amount = (float)$amount; } public function getAmount() { return $this->amount; } public function add($dollar) { $this->amount += $dollar->getAmount(); } } class Work { protected $salary; public function __construct() { $this->salary = new BadDollar(200); } public function payDay() { return $this->salary; } } class Person { public $wallet; } $job = new Work; $p1 = new Person; $p2 = new Person; $p1->wallet = $job->payDay(); print_r($p1->wallet->getAmount()); //200 $p2->wallet = $job->payDay(); print_r($p2->wallet->getAmount()); //200 $p1->wallet->add($job->payDay()); print_r($p1->wallet->getAmount()); //400 //this is bad — actually 400 print_r($p2->wallet->getAmount()); //400 //this is really bad — actually 400 print_r($job->payDay()->getAmount()); //400 |
看上面例子,可以知道明显的错误是$p1和$p2使用的是同一个BadDollar对象,首先,类Work和类Person的实例已经创建。那么,假设每一个雇员最初有一个空的电子钱包,雇员的电子钱包Person:wallet是通过Work::payDay()函数返回的对象资源变量赋值的,所以被设定为一个BadDollar类的对象实例。实际上,$job::salary,、$p1::wallet和$p2::wallet指向的是同一个对象的实例。
使用值对象模式,重新设计Dollar对象如下
代码如下 | 复制代码 |
class Dollar { |
可以看到,主要的变化在于Dollar:add()函数中,它是创建并返回一个新的Dollar实例,所以,尽管你指定当前对象给多个变量,但是每一个变量的变化都不会影响其它的变量实例。
值对象模式设计注意:
1.保护值对象的属性,禁止被直接访问。
2.在构造函数中就对属性进行赋值。
3.去掉任何一个会改变属性值的方式函数(setter),否则属性值很容易被改变
二、策略模式
1.策略模式概念
策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,此模式让算法的变化独立于使用算法的客户。从而让程序结构更灵活,具有更好的扩展性和维护性
2.策略模式结构图
3.策略模式角色说明
抽象策略(Strategy)角色:定义所有支持的算法的公共接口。通常是以一个接口或抽象来实现。Context使用这个接口来调用其ConcreteStrategy定义的算法。
具体策略(ConcreteStrategy)角色:以Strategy接口实现某具体算法
环境(Context)角色:持有一个Strategy类的引用,用一个ConcreteStrategy对象来配置
4.策略模式实例
比如说购物车系统,在给商品计算总价的时候,普通会员肯定是商品单价乘以数量,但是对中级会员提供8者折扣,对高级会员提供7折折扣,这种场景就可以使用策略模式实现:
代码如下 | 复制代码 |
//抽象策略角色《为接口或者抽象类,给具体策略类继承》 |
三、命令模式
1.命令模式概念:
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。
2.参与者:
- Command(命令):在一个方法调用之上定义一个抽象;
- ConcreteCommand(具体的命令):一个操作的实现;
- Invoker(调用者):引用Command实例作为它可用的操作。
代码如下 | 复制代码 |
//命令 interface Validator { /** * The method could have any parameters. * @param mixed * @return boolean */ public function isValid($value); } //具体命令 class MoreThanZeroValidator implements Validator { public function isValid($value) { return $value > 0; } } //具体命令 class EvenValidator implements Validator { public function isValid($value) { return $value % 2 == 0; } } //调用者 class ArrayProcessor { protected $_rule; public function __construct (Validator $rule) { $this->_rule = $rule; } public function process(array $numbers) { foreach ($numbers as $n) { if ($this->_rule->IsValid($n)) { echo $n, " "; } } } } //客户端 $processor = new ArrayProcessor(new EvenValidator()); $processor->process(array(1, 20, 18, 5, 0, 31, 42)); |
在这个模式中,Invoker(调用者)知道传递给它的Command,无需依赖于真实的ConcreteCommand(具体的命令)实现,解决了通过配置进行方法调用相关的问题,如UI控件按钮和菜单等引用一个Command,它们的行为是通过通用的ConcreteCommand实例呈现的。
四、观察者模式
首先了解观察者模式的概念:一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。看下面例子你就明白了!
1.使用观察者模式实现消息推送
代码如下 | 复制代码 |
//观察者
|
-
上一个: php根据身份证号码计算年龄
-
下一个: php获取utf8字符串的字符长度实例
相关文章
- PHP导出数据超时的优化建议解读 10-31
- PHP之mysql位运算解析 10-31
- Laravel实现登录跳转功能解析 10-31
- php双向队列解读 10-31
- Laravel异常上下文解决教程 10-24
- php数组查询元素位置方法介绍 10-24