首页 » Web前端 » php状况机技巧_PHP设计模式之状态模式

php状况机技巧_PHP设计模式之状态模式

访客 2024-10-26 0

扫一扫用手机浏览

文章目录 [+]

GoF类图

状态模式

php状况机技巧_PHP设计模式之状态模式

代码实现

php状况机技巧_PHP设计模式之状态模式
(图片来自网络侵删)

classContext{private$state;publicfunctionSetState(State$state):void{$this->state=$state;}publicfunctionRequest():void{$this->state=$this->state->Handle();}}

一个高下文类,也可以看作是目标类,它的内部有一个状态工具。
当调用Request()的时候,去调用状态类的Handle()方法。
目的是当前高下文类状态的变革都由外部的这个状态类来进行操纵。

interfaceState{publicfunctionHandle():State;}classConcreteStateAimplementsState{publicfunctionHandle():State{echo'当前是A状态',PHP_EOL;returnnewConcreteStateB();}}classConcreteStateBimplementsState{publicfunctionHandle():State{echo'当前是B状态',PHP_EOL;returnnewConcreteStateA();}}

抽象状态接口及两个详细实现。
这两个详细实现实际上是在相互调用。
实现的效果便是高下文类每调用一次Request()方法,内部的状态类就变成别一个状态。
就像一个开关,在打开与关闭中来回切换一样。

$c=newContext();$stateA=newConcreteStateA();$c->SetState($stateA);$c->Request();$c->Request();$c->Request();$c->Request();

客户真个实现,实例化高下文工具并设置初始的状态,然后通过一直的调用Request()工具来实现开关状态的切换。

看出门道了嘛?这里把状态的变革给封装到外部的实现类去了,并不是这个高下文或者目标类内部来进行状态的切换了那么状态模式的意义呢?这个默认类图的例子过于大略,实在状态模式的真正目的是为理解决繁芜的if嵌套问题的,把繁芜的if嵌套条件放到一个个的外部状态类中去判断,在后面的实例中我们会看到适用于:一个工具的行为取决于它的状态,并且它的必须在运行时候根据状态改变自己的行为;一个操作中含有大量的多分支条件语句,且这些分支依赖于该工具的状态;状态模式的特点是:它将与特定状态干系的行为局部化;它使得状态转换显式化;State工具可以被共享;常见于订单系统、会员系统、OA系统中,也便是流程中会涌现各种状态变革的情形,都可以利用状态模式来进行整体的设计与架构

我们的手机系统内定制了自己的商城系统,可以在手机上方便的下单购买我们的商品。
一个订单(Context)会有多种状态(State),比如未支付、已支付、订单完成、订单退款等等一大堆状态。
我们把这些状态都放在了对应的状态类里去实现,不同的状态类都会再去调用该状态下一步的动作,比如已支付后就等待收货、退款后就等待买家填写物流单号等,这样,状态模式就在我们的商城中被灵巧的利用起来咯!

完全代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/22.state/source/state.php

实例

常日的商城运用中都会有会员体系的存在,一样平常等级越高的会员可以享受的折扣也会越多,这个时候,利用状态模式就能很轻松的得到会员的等级折扣。
当然,最紧张的是,利用状态模式可以在须要添加或者删除会员等级时只添加对应的会员折扣状态子类就可以了。
其他业务代码都不须要变动,我们一起来看看详细实现吧!

会员折扣图

会员折扣状态模式版

完全源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/22.state/source/state-member.php

<?phpclassMember{private$state;private$score;publicfunctionSetState($state){$this->state=$state;}publicfunctionSetScore($score){$this->score=$score;}publicfunctionGetScore(){return$this->score;}publicfunctiondiscount(){return$this->state->discount($this);}}interfaceState{publicfunctiondiscount($member);}classPlatinumMemeberStateimplementsState{publicfunctiondiscount($member){if($member->GetScore()>=1000){return0.80;}else{$member->SetState(newGoldMemberState());return$member->discount();}}}classGoldMemberStateimplementsState{publicfunctiondiscount($member){if($member->GetScore()>=800){return0.85;}else{$member->SetState(newSilverMemberState());return$member->discount();}}}classSilverMemberStateimplementsState{publicfunctiondiscount($member){if($member->GetScore()>=500){return0.90;}else{$member->SetState(newGeneralMemberState());return$member->discount();}}}classGeneralMemberStateimplementsState{publicfunctiondiscount($member){return0.95;}}$m=newMember();$m->SetState(newPlatinumMemeberState());$m->SetScore(1200);echo'当前会员'.$m->GetScore().'积分,折扣为:'.$m->discount(),PHP_EOL;$m->SetScore(990);echo'当前会员'.$m->GetScore().'积分,折扣为:'.$m->discount(),PHP_EOL;$m->SetScore(660);echo'当前会员'.$m->GetScore().'积分,折扣为:'.$m->discount(),PHP_EOL;$m->SetScore(10);echo'当前会员'.$m->GetScore().'积分,折扣为:'.$m->discount(),PHP_EOL;

解释

如果不该用状态模式,在Member的discount()方法中,我们可能须要写很多层if...else...判断条件同时,这也带来了方法体会越来越长,越来越难以掩护的问题状态模式正是为理解决这个问题而存在确当discount()行为的结果依赖于Member工具本身的状态(会员分)时,状态模式便是最佳的选择了,也便是上面所说的一个工具的行为取决于它的状态下期看点

状态模式实在利用的范围很广,但利用的人确不多。
毕竟if...else...更加的直不雅观,而且大部分日常运用中的状态一样平常也很少会去修正或添加。
如果你的订单状态须要常常的修正或添加,那肯定在架构设计中存在着问题。
但是,通过这个模式的学习,我们看到了面向工具在处理这种问题时所展现的威力,这才是我们对设计模式学习的终极目的,灵巧得当地利用,更深入的理解面向工具。
好了,末了一个设计模式就要登场了,它便是访问者模式。

标签:

相关文章

房山第一探寻历史文化名区的魅力与发展

房山区,位于北京市西南部,历史悠久,文化底蕴深厚。作为北京市的一个重要组成部分,房山区的发展始终与首都的发展紧密相连。房山区积极推...

Web前端 2025-02-18 阅读1 评论0

手机话费开钻代码数字时代的便捷生活

我们的生活越来越离不开手机。手机话费作为手机使用过程中的重要组成部分,其充值方式也在不断创新。手机话费开钻代码应运而生,为用户提供...

Web前端 2025-02-18 阅读1 评论0

探寻专业奥秘如何查询自己专业的代码

计算机科学已成为当今社会不可或缺的一部分。掌握一门专业代码对于个人发展具有重要意义。面对繁杂的学科体系,如何查询自己专业的代码成为...

Web前端 2025-02-18 阅读0 评论0