您好,登錄后才能下訂單哦!
這篇文章主要介紹“講解PHP設計模式入門之狀態模式原理與實現方法”,在日常操作中,相信很多人在講解PHP設計模式入門之狀態模式原理與實現方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”講解PHP設計模式入門之狀態模式原理與實現方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
想必大家都用過自動售賣的自動飲料機吧,塞入硬幣或紙幣,選擇想要的飲料,飲料就會在機器的下方滾出。大家有沒有相關如果用程序去寫一個飲料機要怎么樣實現呢?
首先我們可以分享一下這部飲料機有幾種狀態
一、沒有錢的狀態
二、有錢的狀態
三、售出的狀態
四、銷售一空的狀態
好吧,知道了這些狀態之后我們開始寫代碼了!
JuiceMachine.php
<?php /** * 飲料機 * @author ben * */ class JuiceMachine{ /** * 糖果機一共存在四種狀態:沒錢,有錢,成功售出以及銷售一空 * * 沒錢的狀態 * @var INT */ const NOMONEY = 0; /** * 有錢的狀態 * @var INT */ const HASMONEY = 1; /** * 成功售出的狀態 * @var INT */ const SOLD = 2; /** * 銷售一空的狀態 * @var INT */ const SOLDOUT = 3; /** * 記錄糖果機當前的狀態,初始化狀態為售空 * @var INT */ private $_state = JuiceMachine::SOLDOUT; /** * 該變量用于記錄飲料機中飲料的數量 */ private $_count; /** * 構造方法,最主要是用來初始化count和state屬性的 */ public function __construct($count){ $this->_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!<br />"; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you just insert a coin<br />"; $this->_state = JuiceMachine::HASMONEY; }elseif($this->_state == JuiceMachine::SOLD){ echo "wait a minute, we are giving you a bottle of juice<br />"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you can't insert coin, the machine is already soldout<br />"; } } /** * 退回硬幣 */ public function retreatCoin(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "coin return!<br />"; $this->_state = JuiceMachine::NOMONEY; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you have'nt inserted a coin yet<br />"; }elseif($this->_state == JuiceMachine::SOLD){ echo "sorry, you already clicked the botton<br />"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you have'nt inserted a coin yet<br />"; } } /** * 點擊飲料對應的按鈕 */ public function clickButton(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "you clicked, we are giving you a bottle of juice...<br />"; $this->_state = JuiceMachine::SOLD; //改變飲料機的狀態為售出模式 $this->dispend(); }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you clicked,but you hav'nt inserted a coin yet<br />"; }elseif($this->_state == JuiceMachine::SOLD){ echo "click twice does'nt get you two bottle of juice<br />"; }elseif($this->_state == JuiceMachine::SOLDOUT){ echo "you clicked, but the machine is already soldout<br />"; } } /** * 發放飲料 */ public function dispend(){ if($this->_state == JuiceMachine::HASMONEY ){ echo "please click the button first<br />"; }elseif($this->_state == JuiceMachine::NOMONEY){ echo "you need to pay first<br />"; }elseif($this->_state == JuiceMachine::SOLD){ echo "now you get you juice<br />"; //飲料機中的飲料數量減一 $this->_count--; if($this->_count <= 0){ echo "opps, runing out of juice<br />"; //如果這時飲料機中沒有飲料了,將飲料機的狀態重置為銷售一空 $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<br />"; } } }
index.php
<?php require_once 'JuiceMachine.php'; $juiceMachine = new JuiceMachine(1); $juiceMachine->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
<?php interface State{ /** * 插入硬幣 */ public function insertCoin(); /** * 回退硬幣 */ public function retreatCoin(); /** * 點擊按鈕 */ public function clickButton(); /** * 發放飲料 */ public function dispend(); }
NomoneyState.php
<?php require_once 'State.php'; class NomoneyState implements State{ /** * 飲料機的實例 * * @var object */ private $_juiceMachine; /** * 構造方法,主要用于初始化飲料機實例 * */ public function __construct($juiceMachine){ $this->_juiceMachine = $juiceMachine; } /* (non-PHPdoc) * @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "you just insert a coin<br />"; //將飲料機的狀態切換成有錢的狀態 $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<br />"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "you clicked,but you hav'nt inserted a coin yet<br />"; } /* (non-PHPdoc) * @see State::dispend() */ public function dispend() { // TODO Auto-generated method stub echo "you need to pay first<br />"; } }
HasmoneyState.php
<?php require_once 'State.php'; class HasmoneyState implements State { /** * 飲料機的實例 * * @var object */ private $_juiceMachine; /** * 構造方法,主要用于初始化飲料機實例 */ public function __construct($juiceMachine) { $this->_juiceMachine = $juiceMachine; } /* * (non-PHPdoc) @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub echo "you can't insert another coin!<br />"; } /* * (non-PHPdoc) @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "coin return!<br />"; $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...<br />"; // 改變飲料機的狀態為售出模式 $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<br />"; } }
SoldoutState.php
<?php require_once 'State.php'; class SoldoutState implements State{ /** * 飲料機的實例 * * @var object */ private $_juiceMachine; /** * 構造方法,主要用于初始化飲料機實例 * */ public function __construct($juiceMachine){ $this->_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<br />"; } /* (non-PHPdoc) * @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "you have'nt inserted a coin yet<br />"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "you clicked, but the machine is already soldout<br />"; } /* (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<br />"; } }
SoldState.php
<?php require_once 'State.php'; class SoldState implements State{ /** * 飲料機的實例 * * @var object */ private $_juiceMachine; /** * 構造方法,主要用于初始化飲料機實例 * */ public function __construct($juiceMachine){ $this->_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<br />"; } /* (non-PHPdoc) * @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "sorry, you already clicked the botton<br />"; } /* (non-PHPdoc) * @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "click twice does'nt get you two bottle of juice<br />"; } /* (non-PHPdoc) * @see State::dispend() */ public function dispend() { $this->_juiceMachine->decJuice(); if($this->_juiceMachine->getCount() <= 0){ echo "opps, runing out of juice<br />"; //如果這時飲料機中沒有飲料了,將飲料機的狀態重置為銷售一空 $this->_juiceMachine->setState($this->_juiceMachine->getSoldoutState()); }else{ //將飲料機的狀態重置為沒有錢 $this->_juiceMachine->setState($this->_juiceMachine->getNomoneyState()); } } }
WinnerState.php
<?php require_once 'State.php'; class WinnerState implements State { /** * 飲料機的實例 * * @var object */ private $_juiceMachine; /** * 構造方法,主要用于初始化飲料機實例 */ public function __construct($juiceMachine) { $this->_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<br />"; } /* * (non-PHPdoc) @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub echo "sorry, you already clicked the botton<br />"; } /* * (non-PHPdoc) @see State::clickButton() */ public function clickButton() { // TODO Auto-generated method stub echo "click twice does'nt get you two bottle of juice<br />"; } /* * (non-PHPdoc) @see State::dispend() */ public function dispend() { echo "you are a winner! you get two bottle of juice!<br />"; $this->_juiceMachine->decJuice(); if ($this->_juiceMachine->getCount() > 0) { $this->_juiceMachine->decJuice(); if ($this->_juiceMachine->getCount() <= 0) { echo "opps, runing out of juice<br />"; // 如果這時飲料機中沒有飲料了,將飲料機的狀態重置為銷售一空 $this->_juiceMachine->setState($this->_juiceMachine->getSoldoutState()); } else { // 將飲料機的狀態重置為沒有錢 $this->_juiceMachine->setState($this->_juiceMachine->getSoldoutState()); } } else { echo "opps, runing out of juice<br />"; // 如果這時飲料機中沒有飲料了,將飲料機的狀態重置為銷售一空 $this->_juiceMachine->setState($this->_juiceMachine->getSoldoutState()); } } }
JuiceMachine.php
<?php require_once './state/NomoneyState.php'; require_once './state/HasmoneyState.php'; require_once './state/SoldState.php'; require_once './state/SoldoutState.php'; require_once './state/WinnerState.php'; class JuiceMachine { /** * 記錄糖果機當前的狀態,初始化狀態為售空 * * @var object */ private $_state; /** * 該變量用于記錄飲料機中飲料的數量 */ private $_count; /** * 構造方法,最主要是用來初始化count和state屬性的 */ public function __construct($count) { $this->_state = new SoldoutState($this); $this->_count = $count; // 當飲料機中的飲料數量大于零時,將飲料機的狀態重置為沒有錢的狀態。 if ($this->_count > 0) { $this->_state = new NomoneyState($this); } } /* * (non-PHPdoc) @see State::insertCoin() */ public function insertCoin() { // TODO Auto-generated method stub $this->_state->insertCoin(); } /* * (non-PHPdoc) @see State::retreatCoin() */ public function retreatCoin() { // TODO Auto-generated method stub $this->_state->retreatCoin(); } /* * (non-PHPdoc) @see State::clickButton() */ public function clickButton() { $this->_state->clickButton(); //其實發放糖果是在用戶點擊完按鈕后機器內部進行的所有沒有必要再寫一個dispend方法 $this->_state->dispend(); } /** * 設置糖果機的狀態 * * @param State $state */ public function setState(State $state) { $this->_state = $state; } /** * 獲取沒有錢的狀態 */ public function getNomoneyState(){ return new NomoneyState($this); } /** * 獲取有錢的狀態 */ public function getHasmoneyState(){ return new HasmoneyState($this); } /** * 獲取售出的狀態 */ public function getSoldState(){ return new SoldState($this); } /** * 獲取銷售一空的狀態 */ public function getSoldoutState(){ return new SoldoutState($this); } /** * 獲取幸運者的狀態 */ public function getWinnerState(){ return new WinnerState($this); } /** * 獲取飲料機中飲料的數量 */ public function getCount(){ return $this->_count; } /** * 將飲料數量減一 */ public function decJuice(){ echo "now you get you juice<br />"; //飲料機中的飲料數量減一 $this->_count--; } }
index.php
<?php require_once 'JuiceMachine.php'; $juiceMachine = new JuiceMachine(2); $juiceMachine->insertCoin(); $juiceMachine->clickButton();
到此,關于“講解PHP設計模式入門之狀態模式原理與實現方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。