詳解PHP中的狀態(tài)模式編程
定義
狀態(tài)模式,又稱狀態(tài)對象模式(Pattern of Objects for State),狀態(tài)模式就是對象的行為模式。狀態(tài)模式允許一個對象在其內(nèi)部狀態(tài)改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣
UML圖

狀態(tài)模式中主要角色
抽象狀態(tài)角色(State):定義一個接口或抽象類State,用以封裝環(huán)境對象的一個特定的狀態(tài)所對應(yīng)的行為
具體狀態(tài)(ConcreteState)角色:每一個狀態(tài)類都實現(xiàn)了環(huán)境(Context)的一個狀態(tài)所對應(yīng)的行為
環(huán)境(Context)角色:定義客戶端所感興趣的接口,并且保留一個具體狀態(tài)類的實例。這個具體狀態(tài)類的實例給出此環(huán)境對象的現(xiàn)有狀態(tài)
使用場景
考慮一個在線投票系統(tǒng)的應(yīng)用,要實現(xiàn)控制同一用戶只能投一票,如果一個用戶反復(fù)投票,而且投票超過5次,則判定為惡意刷票,如果投票超過8次,需要加入黑名單
要使用狀態(tài)模式實現(xiàn),首先要把投票過程的各種狀態(tài)定義出來,根據(jù)以上描述大致分為四種狀態(tài):正常投票,惡意投票,黑名單投票。然后創(chuàng)建一個投票管理對象(相當(dāng)于Context)
UML圖

示例代碼
<?php
/**
* 抽象狀態(tài)類
* @author wzy
*
*/
interface VoteState
{
/**
* 需要實現(xiàn)的公共方法
*/
public function vote ();
}
/**
* 具體狀態(tài)——正常投票
*
* @author wzy
*
*/
class NormalVoteState implements VoteState
{
public function vote ()
{
echo "這是一個正常投票!";
}
}
/**
* 具體狀態(tài)——惡意投票
*
* @author wzy
*
*/
class RepeatVoteState implements VoteState
{
public function vote ()
{
echo "這是一個惡意投票!";
}
}
/**
* 具體狀態(tài)——黑名單投票
*
* @author wzy
*
*/
class BlockVoteState implements VoteState
{
public function vote ()
{
echo "這是一個黑名單投票!";
}
}
/**
* Context角色
*/
class VoteManager
{
/**
* 投票數(shù)量
*
* @var int
*/
private $vote_count;
/**
* 狀態(tài)類實例
*
* @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)和行為
所謂對象的狀態(tài),通常指的就是對象實例的屬性的值;而行為指的就是對象的功能,在具體一點說,行為大多可以對應(yīng)到方法上
狀態(tài)模式的功能就是分離狀態(tài)的行為,通過維護(hù)狀態(tài)的變化,來調(diào)用不同狀態(tài)對應(yīng)的功能。也就是說,狀態(tài)和行為是相關(guān)聯(lián)的,它們的關(guān)系可以描述為:狀態(tài)決定行為
由于狀態(tài)是在運行期被改變的,因為行為也會在運行期根據(jù)狀態(tài)的改變而改變
環(huán)境和狀態(tài)處理對象
在狀態(tài)模式中,環(huán)境(Context)是持有狀態(tài)的對象,但是環(huán)境自己并不處理跟狀態(tài)相關(guān)的行為,而是把處理狀態(tài)的功能委托給了狀態(tài)對應(yīng)的狀態(tài)處理類來處理
在具體的狀態(tài)處理中經(jīng)常需要獲取環(huán)境(Context)自身的數(shù)據(jù),可以考慮用抽象類替代接口,這樣可能會更方便參數(shù)的傳遞
客戶端一般只與環(huán)境(Context)交互??蛻舳丝梢杂脿顟B(tài)對象來配置一個環(huán)境(Context),一旦配置完畢,就不再需要和狀態(tài)對象打交道了??蛻舳送ǔ2回?fù)責(zé)運行期間的狀態(tài)維護(hù),也不負(fù)責(zé)后續(xù)到底使用哪一個具體的狀態(tài)處理對象
相關(guān)文章
PHP遠(yuǎn)程連接oracle數(shù)據(jù)庫操作實現(xiàn)方法圖文詳解
這篇文章主要介紹了PHP遠(yuǎn)程連接oracle數(shù)據(jù)庫操作實現(xiàn)方法,結(jié)合圖文形式詳細(xì)分析了php連接Oracle數(shù)據(jù)庫的相關(guān)配置、實現(xiàn)方法、遇到的問題、解決方法及相關(guān)操作注意事項,需要的朋友可以參考下2019-04-04
php 自寫函數(shù)代碼 獲取關(guān)鍵字 去超鏈接
根據(jù)權(quán)重獲取關(guān)鍵字 去掉文章中的超鏈接簡單,簡潔2010-02-02
關(guān)于PHP模板Smarty的初級使用方法以及心得分享
本篇文章是對PHP模板Smarty的初級使用方法以及心得進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
php實現(xiàn)過濾表單提交中html標(biāo)簽的方法
這篇文章主要介紹了php實現(xiàn)過濾表單提交中html標(biāo)簽的方法,并以<br/>標(biāo)簽為例演示了過濾的方法,非常實用,需要的朋友可以參考下2014-10-10
PHP 長文章分頁函數(shù) 帶使用方法,不會分割段落,翻頁在底部
PHP 長文章分頁函數(shù) 帶使用方法,不會分割段落,翻頁在底部 ,需要的朋友可以參考下。2009-10-10

