设为首页 收藏本站
查看: 481|回复: 0

[经验分享] Php设计模式:行为型模式(三)

[复制链接]

尚未签到

发表于 2017-4-4 11:36:20 | 显示全部楼层 |阅读模式
原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=12
 可以在线运行查看效果哦!    
 
<接上一篇>
7、职责链模式 (Chainof Responsibility):
         多个对象有机会处理请求,为请求发送者和接收者解耦。就像银行里的取款机,不管那一台都可以取到钱。
         好处:简单化对象隐藏链结构,便于添加新职责节点。
         弊端:请求可能没有接受者,或者被多个接收者调用,性能降低。
         应用场景:处理多种请求。
代码实现:

<?php
/**
* 优才网公开课示例代码
*
* 职责链模式 Chain of Responsibility
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
function output($string) {
echo    $string . "\n";
}
/**
* 加入在公司里,如果你的请假时间小于0.5天,那么只需要向leader打声招呼就OK了。
  如果0.5<=请假天数<=3天,需要先leader打声招呼,然后部门经理签字。
  如果3<请假天数,需要先leader打声招呼,然后到部门经理签字,最后总经经理确认签字,
如果请假天数超过10天,是任何人都不能批准的。
*/

/**
* 抽象处理者角色(Handler:Approver):定义一个处理请求的接口,和一个后继连接(可选)
*
*/  
abstract class Handler
{  
protected $_handler = null;  
protected $_handlerName = null;  
public function setSuccessor($handler)  
{  
$this->_handler = $handler;  
}  
protected  function _success($request)  
{  
output(sprintf("%s's request was passed", $request->getName()));
return true;  
}  
abstract function handleRequest($request);  
}  
/**
* 具体处理者角色(ConcreteHandler:President):处理它所负责的请求,可以访问后继者,如果可以处理请求则处理,否则将该请求转给他的后继者。
*
*/  
class ConcreteHandlerLeader extends Handler  
{  
function __construct($handlerName){  
$this->_handlerName = $handlerName;  
}  
public function handleRequest($request)  
{  
if($request->getDay() < 0.5) {  
output(sprintf('%s was told', $this->_handlerName));       // 已经跟leader招呼了
return $this->_success($request);  
}   
if ($this->_handler instanceof Handler) {  
return $this->_handler->handleRequest($request);  
}  
}  
}  
/**
* Manager
*
*/  
class ConcreteHandlerManager extends Handler  
{  
function __construct($handlerName){  
$this->_handlerName = $handlerName;  
}  
public function handleRequest($request)  
{  
if(0.5 <= $request->getDay() && $request->getDay()<=3) {  
output(sprintf('%s signed', $this->_handlerName));       // 部门经理签字
return $this->_success($request);  
}   
if ($this->_handler instanceof Handler) {  
return $this->_handler->handleRequest($request);  
}  
}  
}  
class ConcreteHandlerGeneralManager extends Handler  
{  
function __construct($handlerName){  
$this->_handlerName = $handlerName;  
}  
public function handleRequest($request)  
{  
if(3 < $request->getDay() && $request->getDay() < 10){  
output(sprintf('%s signed', $this->_handlerName));       // 总经理签字
return $this->_success($request);  
}  
if ($this->_handler instanceof Handler) {  
return $this->_handler->handleRequest($request);  
} else {
output(sprintf('no one can approve request more than 10 days'));
}
}  
}  
/**
* 请假申请
*
*/  
class Request  
{  
private $_name;  
private $_day;  
private $_reason;  
function __construct($name= '', $day= 0, $reason = ''){  
$this->_name = $name;  
$this->_day = $day;  
$this->_reason = $reason;  
}  
public function setName($name){  
$this->_name = $name;  
}  
public function getName(){  
return  $this->_name;  
}  
public function setDay($day){  
$this->_day = $day;  
}  
public function getDay(){  
return  $this->_day ;  
}  
public function setReason($reason ){  
$this->_reason = $reason;  
}  
public function getReason( ){  
return  $this->_reason;  
}  
}  

class Client {  
public static function test(){  
$leader = new ConcreteHandlerLeader('leader');  
$manager = new ConcreteHandlerManager('manager');  
$generalManager = new ConcreteHandlerGeneralManager('generalManager');  
//请求实例  
$request = new Request('ucai',4,'休息');  
$leader->setSuccessor($manager);  
$manager->setSuccessor($generalManager);  
$result =  $leader->handleRequest($request);  
}  
}  
Client::test();

 
8、策略模式(Strategy):
        定义一系列算法,把每一个算法封装起来,并且使它们可相互替换。就像篮球队里的球员,场上的和场下休息的。教练可以让场上的下来,也可以让场下的上阵。
        好处:定义可重用的一系列算法和行为,并且消除了if else语句。
        弊端:调用端必须知道所有策略类。
        应用场景:用于对象间的替换。
代码实现:

<?php
/**
* 优才网公开课示例代码
*
* 策略模式 Strategy
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/

function output($string) {
echo    $string . "\n";
}
//策略基类接口
interface IStrategy {
public function OnTheWay();
}
class WalkStrategy implements IStrategy {
public function OnTheWay() {
output( '在路上步行');
}
}
class RideBickStrategy implements IStrategy {
public function OnTheWay() {
output( '在路上骑自行车');
}
}
class CarStrategy implements IStrategy {
public function OnTheWay() {
output( '在路上开车');
}
}
//选择策略类Context
class Context {
public function find($strategy) {
$strategy->OnTheWay();
}
}
class Client {  
public static function test(){  
$travel = new Context();
$travel->find(new WalkStrategy());
$travel->find(new RideBickStrategy());
$travel->find(new CarStrategy());
}  
}  
Client::test();

 
已知模式
1、备忘录模式(Memento):
         保存对象在一时刻的状态。亲,还记得“老师来了记得叫我一下”的同桌的他吗?
         好处:给用户提供了一种可以恢复状态的机制。
         弊端:消耗资源。
         应用场景:用于需要保存的数据。
代码实现:

<?php
/**
* 优才网公开课示例代码
*
* 备忘录模式 Memento
*
* @author 优才网全栈工程师教研组
* @see http://www.ucai.cn
*/
function output($string) {
echo    $string . "\n";
}

class Originator { // 发起人(Originator)角色
private $_state;
public function __construct() {
$this->_state = '';
}
public function createMemento() { // 创建备忘录
return new Memento($this->_state);
}
public function restoreMemento(Memento $memento) { // 将发起人恢复到备忘录对象记录的状态上
$this->_state = $memento->getState();
}
public function setState($state) { $this->_state = $state; }
public function getState() { return $this->_state; }
public function showState() {
output($this->_state);
}
}
class Memento { // 备忘录(Memento)角色
private $_state;
public function __construct($state) {
$this->setState($state);
}
public function getState() { return $this->_state; }
public function setState($state) { $this->_state = $state;}
}
class Caretaker { // 负责人(Caretaker)角色
private $_memento;
public function getMemento() { return $this->_memento; }
public function setMemento(Memento $memento) { $this->_memento = $memento; }
}
class Client {  
public static function test(){  
$org = new Originator();
$org->setState('open');
$org->showState();
/* 创建备忘 */
$memento = $org->createMemento();
/* 通过Caretaker保存此备忘 */
$caretaker = new Caretaker();
$caretaker->setMemento($memento);
/* 改变目标对象的状态 */
$org->setState('close');
$org->showState();
/* 还原操作 */
$org->restoreMemento($caretaker->getMemento());
$org->showState();
}  
}  
Client::test();

return;

try {
$db->beginTransaction();
$succ   = $db->exec($sql_1);
if (!$succ) {
throw new Exception('SQL 1 update failed');
}
$succ   = $db->exec($sql_2);
if (!$succ) {
throw new Exception('SQL 2 update failed');
}
$succ   = $db->exec($sql_3);
if (!$succ) {
throw new Exception('SQL 3 update failed');
}
$db->commit();
} catch (Exception $exp) {
$db->rollBack();
}

 
深度模式
1、解释器模式(Interpreter):
         定义语言的文法,并建立一个解释器解释该语言中的句子。每个用过字典的童鞋都懂滴。
         好处:可扩展性比较好,灵活性大。
         弊端:可能难以维护复杂的文法。
         应用场景:用于成对或者一对多的需求中。
 
2、访问者模式(Visitor):
        封装某些用于作用于某种数据结构中各元素的操作,可以在不改变数据结构的前提下定义作用于这些元素的新操作。如银行排号机。
        好处:将相关的事物集中到一个访问者对象中。
        弊端:增加新数据结构很困难。
        应用场景:排队,排号。
 
三、总结
        
        本篇介绍了行为型模式,行为模式涉及到算法和对象职责间的分配,行为类模式采用继承机制在类间分派行为,TemplateMethod和Interpreter是类行为模式。行为对象模式使用对象复合而不是继承,一些行为对象模式描述了一组相互对等的对象如何相互协作以完成其中任何一个对象都单独无法完成的任务,如Mediator在对象间引入一个mediator对象提供了松耦合所需的间接性;Chain of Responsibility提供了更松的耦合,它通过一条候选对象链隐式的向一个对象发松请求,可以运行时刻决定哪些候选者参与到链中;Observer定义并保持了对象间的依赖关系;其它的行为对象模式常将行为封装封装在一个对象中,并将请求指派给它,Strategy模式将算法封装在对象中,这样可以方面的改变和指定一个对象所使用的算法;Command模式将请求封装在对象中,这样它就可以作为参数来传递,已可以存储在历史列表中或以其它方式使用;State模式封装一个对象的状态,使得当这个对象的状态对象变化时,该对象可改变它的行为;Visitor模式封装分布于多个类之间的行为;而Iterator模式则抽象了访问和遍历一个集合中对象的方式。
 
优才网免费公开课链接: http://www.ucai.cn/course5/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-360024-1-1.html 上篇帖子: 中文转拼音的PHP类 下篇帖子: php实现验证码的识别
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表