您现在的位置是:网站首页> 编程资料编程资料
PHP设计模式入门之状态模式原理与实现方法分析_php实例_
2023-05-25
259人已围观
简介 PHP设计模式入门之状态模式原理与实现方法分析_php实例_
本文实例讲述了PHP设计模式入门之状态模式原理与实现方法。分享给大家供大家参考,具体如下:
想必大家都用过自动售卖的自动饮料机吧,塞入硬币或纸币,选择想要的饮料,饮料就会在机器的下方滚出。大家有没有相关如果用程序去写一个饮料机要怎么样实现呢?
首先我们可以分享一下这部饮料机有几种状态
一、没有钱的状态
二、有钱的状态
三、售出的状态
四、销售一空的状态
好吧,知道了这些状态之后我们开始写代码了!
JuiceMachine.php
_count = $count; //当饮料机中的饮料数量大于零时,将饮料机的状态重置为没有钱的状态。 if($this->_count > 0){ $this->_state = JuiceMachine::NOMONEY; } } /** * 投入硬币 */ public function insertCoin(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "you can't insert another coin!
"; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you just insert a coin
"; $this->_state = JuiceMachine::HASMONEY; }elseif($this->_state == JuiceMachine::SOLD){ echo "wait a minute, we are giving you a bottle of juice
"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you can't insert coin, the machine is already soldout
"; } } /** * 退回硬币 */ public function retreatCoin(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "coin return!
"; $this->_state = JuiceMachine::NOMONEY; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you have'nt inserted a coin yet
"; }elseif($this->_state == JuiceMachine::SOLD){ echo "sorry, you already clicked the botton
"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you have'nt inserted a coin yet
"; } } /** * 点击饮料对应的按钮 */ public function clickButton(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "you clicked, we are giving you a bottle of juice...
"; $this->_state = JuiceMachine::SOLD; //改变饮料机的状态为售出模式 $this->dispend(); }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you clicked,but you hav'nt inserted a coin yet
"; }elseif($this->_state == JuiceMachine::SOLD){ echo "click twice does'nt get you two bottle of juice
"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you clicked, but the machine is already soldout
"; } } /** * 发放饮料 */ public function dispend(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "please click the button first
"; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you need to pay first
"; }elseif($this->_state == JuiceMachine::SOLD){ echo "now you get you juice
"; //饮料机中的饮料数量减一 $this->_count--; if($this->_count <= 0){ echo "opps, runing out of juice
"; //如果这时饮料机中没有饮料了,将饮料机的状态重置为销售一空 $this->_state = JuiceMachine::SOLDOUT; }else{ //将饮料机的状态重置为没有钱 $this->_state = JuiceMachine::NOMONEY; } }elseif($this->_state == JuiceMachine::SOLDOUT){ //其实这种情况不应该出现 echo "opps, it appears that we don't have any juice left
"; } } } index.php
insertCoin(); $juiceMachine->clickButton();
运行的结果是:
you just insert a coin
you clicked, we are giving you a bottle of juice...
now you get you juice
opps, runing out of juice
到目前为止我们的程序运行良好,没有出现什么问题,但是从这些多重的if判断中你是否嗅到了坏代码的味道呢?有一天问题终于出现了,老板希望当用户点击按钮时有10%的概率拿到两瓶饮料,我们需要为饮料机多加一个状态,这时去修改代码就成为了一种灾难,而且很可能会影响到之前的代码,带来新的bug,看看状态模式如何帮助我们度过难关吧!
状态模式的官方定义是:状态模式允许对象在内部状态改变是改变它的行为,对象看起来好像是修改了它的类
用uml类图表示如下:

在我们这个项目中的实际类图如下:

具体实现代码:
State.php
NomoneyState.php
_juiceMachine = $juiceMachine; } /* (non-PHPdoc) * @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "you just insert a coin
"; //将饮料机的状态切换成有钱的状态 $this->_juiceMachine->setState($this->_juiceMachine->getHasmoneyState()); } /* (non-PHPdoc) * @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "you have'nt inserted a coin yet
"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "you clicked,but you hav'nt inserted a coin yet
"; } /* (non-PHPdoc) * @see State::dispend() */ public function dispend() { // TODO Auto-generated method stub echo "you need to pay first
"; } } HasmoneyState.php
_juiceMachine = $juiceMachine; } /* * (non-PHPdoc) @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "you can't insert another coin!
"; } /* * (non-PHPdoc) @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "coin return!
"; $this->_juiceMachine->setState($this->_juiceMachine->getNomoneyState()); } /* * (non-PHPdoc) @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "you clicked, we are giving you a bottle of juice...
"; // 改变饮料机的状态为售出模式 $rand = mt_rand(0, 0); // 当随机数为0(即1/10的概率)并且饮料机中还有1瓶以上的饮料时 if ($rand == 0 && $this->_juiceMachine->getCount() > 1) { $this->_juiceMachine->setState($this->_juiceMachine->getWinnerState()); } else { $this->_juiceMachine->setState($this->_juiceMachine->getSoldState()); } } /* * (non-PHPdoc) @see State::dispend() */ public function dispend() { // TODO Auto-generated method stub echo "please click the button first
"; } } SoldoutState.php
_juiceMachine = $juiceMachine; } /* (non-PHPdoc) * @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "you can't insert coin, the machine is already soldout
"; } /* (non-PHPdoc) * @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "you have'nt inserted a coin yet
"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "you clicked, but the machine is already soldout
"; } /* (non-PHPdoc) * @see State::dispend() */ public function dispend() { // TODO Auto-generated method stub echo "opps, it appears that we don't have any juice left
"; } } SoldState.php
_juiceMachine = $juiceMachine; } /* (non-PHPdoc) * @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "wait a minute, we are giving you a bottle of juice
"; } /* (non-PHPdoc) * @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "sorry, you already clicked the botton
"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "click twice does'nt get you two bottle of juice
"; } /* (non-PHPdoc) * @see State::dispend() */ public function dispend() { $this->_juiceMachine->decJuice(); if($this->_juiceMachine->getCount() <= 0){ echo "opps, runing out of juice
"; //如果这时饮料机中没有饮料了,将饮料机的状态重置为销售一空 $this->_juiceMachine->setState($this->_juiceMachine->getSoldoutState()); }else{ //将饮料机的状态重置为没有钱 $this->_juiceMachine->setState($this->_juiceMachine->getNomoneyState()); } } } WinnerState.php
_juiceMachine = $juiceMachine; } /* * (non-PHPdoc) @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "wait a minute, we are giving you a bottle of juice
"; } /* * (non-PHPdoc) @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "sorry, you already clicked the botton
"; } /* * (non-PHPdoc) @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "click twice does'nt get you two bottle of juice
"; } /* * (non-PHPdoc) @see State::dispend() */ public function dispend() { echo "you are a winner! you get two bottle of juice!
"; $this->_juiceMachine->decJuice(); if ($this->_juiceMachine->getCount() > 0) { $this->_juiceMachine->decJuice(); if ($this->_juiceMachine->getCount() <= 0) { echo "opps, runing out of juice<
相关内容
- PHP设计模式入门之迭代器模式原理与实现方法分析_php实例_
- PHP中迭代器的简单实现及Yii框架中的迭代器实现方法示例_php实例_
- PHP设计模式之迭代器模式Iterator实例分析【对象行为型】_php实例_
- Yii Framework框架开发微信公众平台示例_php实例_
- PHP随机生成中文段落示例【测试网站内容时使用】_php技巧_
- PHP过滤器 filter_has_var() 函数用法实例分析_php技巧_
- PHP优化之批量操作MySQL实例分析_php技巧_
- Thinkphp 框架扩展之Widget扩展实现方法分析_php实例_
- Thinkphp 框架扩展之行为扩展原理与实现方法分析_php实例_
- Thinkphp 框架扩展之标签库驱动原理与用法分析_php实例_
点击排行
本栏推荐
