詳解PHP中的狀態(tài)模式編程
定義
狀態(tài)模式,又稱狀態(tài)對(duì)象模式(Pattern of Objects for State),狀態(tài)模式就是對(duì)象的行為模式。狀態(tài)模式允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候改變其行為。這個(gè)對(duì)象看上去就像是改變了它的類一樣
UML圖
狀態(tài)模式中主要角色
抽象狀態(tài)角色(State):定義一個(gè)接口或抽象類State,用以封裝環(huán)境對(duì)象的一個(gè)特定的狀態(tài)所對(duì)應(yīng)的行為
具體狀態(tài)(ConcreteState)角色:每一個(gè)狀態(tài)類都實(shí)現(xiàn)了環(huán)境(Context)的一個(gè)狀態(tài)所對(duì)應(yīng)的行為
環(huán)境(Context)角色:定義客戶端所感興趣的接口,并且保留一個(gè)具體狀態(tài)類的實(shí)例。這個(gè)具體狀態(tài)類的實(shí)例給出此環(huán)境對(duì)象的現(xiàn)有狀態(tài)
使用場(chǎng)景
考慮一個(gè)在線投票系統(tǒng)的應(yīng)用,要實(shí)現(xiàn)控制同一用戶只能投一票,如果一個(gè)用戶反復(fù)投票,而且投票超過5次,則判定為惡意刷票,如果投票超過8次,需要加入黑名單
要使用狀態(tài)模式實(shí)現(xiàn),首先要把投票過程的各種狀態(tài)定義出來,根據(jù)以上描述大致分為四種狀態(tài):正常投票,惡意投票,黑名單投票。然后創(chuàng)建一個(gè)投票管理對(duì)象(相當(dāng)于Context)
UML圖
示例代碼
<?php /** * 抽象狀態(tài)類 * @author wzy * */ interface VoteState { /** * 需要實(shí)現(xiàn)的公共方法 */ public function vote (); } /** * 具體狀態(tài)——正常投票 * * @author wzy * */ class NormalVoteState implements VoteState { public function vote () { echo "這是一個(gè)正常投票!"; } } /** * 具體狀態(tài)——惡意投票 * * @author wzy * */ class RepeatVoteState implements VoteState { public function vote () { echo "這是一個(gè)惡意投票!"; } } /** * 具體狀態(tài)——黑名單投票 * * @author wzy * */ class BlockVoteState implements VoteState { public function vote () { echo "這是一個(gè)黑名單投票!"; } } /** * Context角色 */ class VoteManager { /** * 投票數(shù)量 * * @var int */ private $vote_count; /** * 狀態(tài)類實(shí)例 * * @var object */ private $voteInstance; /** * 構(gòu)造函數(shù),初始化成員屬性 * * @param int $count */ public function __construct ($count = 1) { $this->vote_count = $count; } /** * 客戶端調(diào)用的接口函數(shù) */ public function setState ($count) { if (! is_null($count)) { $this->vote_count = $count; } if ($this->vote_count < 5) { $this->voteInstance = new NormalVoteState(); } else if ($this->vote_count < 8) { $this->voteInstance = new RepeatVoteState(); } else { $this->voteInstance = new BlockVoteState(); } $this->voteInstance->vote(); } } /** * 模擬客戶端操作 */ $object = new VoteManager(); $object->setState(1); echo "<br>"; $object->setState(6); echo "<br>"; $object->setState(10);
回顧狀態(tài)模式
狀態(tài)和行為
所謂對(duì)象的狀態(tài),通常指的就是對(duì)象實(shí)例的屬性的值;而行為指的就是對(duì)象的功能,在具體一點(diǎn)說,行為大多可以對(duì)應(yīng)到方法上
狀態(tài)模式的功能就是分離狀態(tài)的行為,通過維護(hù)狀態(tài)的變化,來調(diào)用不同狀態(tài)對(duì)應(yīng)的功能。也就是說,狀態(tài)和行為是相關(guān)聯(lián)的,它們的關(guān)系可以描述為:狀態(tài)決定行為
由于狀態(tài)是在運(yùn)行期被改變的,因?yàn)樾袨橐矔?huì)在運(yùn)行期根據(jù)狀態(tài)的改變而改變
環(huán)境和狀態(tài)處理對(duì)象
在狀態(tài)模式中,環(huán)境(Context)是持有狀態(tài)的對(duì)象,但是環(huán)境自己并不處理跟狀態(tài)相關(guān)的行為,而是把處理狀態(tài)的功能委托給了狀態(tài)對(duì)應(yīng)的狀態(tài)處理類來處理
在具體的狀態(tài)處理中經(jīng)常需要獲取環(huán)境(Context)自身的數(shù)據(jù),可以考慮用抽象類替代接口,這樣可能會(huì)更方便參數(shù)的傳遞
客戶端一般只與環(huán)境(Context)交互。客戶端可以用狀態(tài)對(duì)象來配置一個(gè)環(huán)境(Context),一旦配置完畢,就不再需要和狀態(tài)對(duì)象打交道了??蛻舳送ǔ2回?fù)責(zé)運(yùn)行期間的狀態(tài)維護(hù),也不負(fù)責(zé)后續(xù)到底使用哪一個(gè)具體的狀態(tài)處理對(duì)象
- PHP設(shè)計(jì)模式之責(zé)任鏈模式的深入解析
- 簡(jiǎn)單介紹PHP的責(zé)任鏈編程模式
- php+ajax發(fā)起流程和審核流程(以請(qǐng)假為例)
- php注冊(cè)審核重點(diǎn)解析(數(shù)據(jù)訪問)
- 如何用PHP做到頁面注冊(cè)審核
- PHP代碼審核的詳細(xì)介紹
- PHP設(shè)計(jì)模式之狀態(tài)模式定義與用法詳解
- 學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)狀態(tài)模式
- php設(shè)計(jì)模式 State (狀態(tài)模式)
- PHP實(shí)現(xiàn)基于狀態(tài)的責(zé)任鏈審批模式詳解
相關(guān)文章
PHP采用自定義函數(shù)實(shí)現(xiàn)遍歷目錄下所有文件的方法
這篇文章主要介紹了PHP采用自定義函數(shù)實(shí)現(xiàn)遍歷目錄下所有文件的方法,是PHP程序開發(fā)中常見的功能,需要的朋友可以參考下2014-08-08phpstorm斷點(diǎn)調(diào)試方法圖文詳解
這篇文章主要介紹了phpstorm斷點(diǎn)調(diào)試方法,結(jié)合圖文形式詳細(xì)分析了phpstorm斷點(diǎn)調(diào)試的基本配置方法、使用技巧與注意事項(xiàng),需要的朋友可以參考下2023-04-04php封裝的pdo數(shù)據(jù)庫操作工具類與用法示例
這篇文章主要介紹了php封裝的pdo數(shù)據(jù)庫操作工具類與用法,結(jié)合實(shí)例形式分析了php封裝的pdo數(shù)據(jù)庫連接、增刪改查、錯(cuò)誤處理、關(guān)閉連接等操作及相關(guān)使用技巧,需要的朋友可以參考下2019-05-05php中的實(shí)現(xiàn)trim函數(shù)代碼
trim() 函數(shù)從字符串的兩端刪除空白字符和其他預(yù)定義字符。2007-03-03php 獲取今日、昨日、上周、本月的起始時(shí)間戳和結(jié)束時(shí)間戳的方法
php 獲取今日、昨日、上周、本月的起始時(shí)間戳和結(jié)束時(shí)間戳的方法,主要使用到了 php 的時(shí)間函數(shù) mktime,下面首先還是直奔主題以示例說明如何使用 mktime 獲取今日、昨日、上周、本月的起始時(shí)間戳和結(jié)束時(shí)間戳,然后在介紹一下 mktime 函數(shù)作用和用法2013-09-09PHP 7.1中AES加解密方法mcrypt_module_open()的替換方案
這篇文章主要給大家介紹了關(guān)于PHP 7.1中AES加解密方法mcrypt_module_open()替換方案的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10[PHP]經(jīng)常用到的實(shí)用函數(shù)集合
[PHP]經(jīng)常用到的實(shí)用函數(shù)集合...2007-11-11