標籤:
狀態模式
輸入訊號是事件;輸出是狀態結果,狀態模式狀態機器就是一個黑盒子。
狀態模式主要突出了兩個字:”改變”,對象的狀態決定了狀態的行為,事物的本質決定了事物的行為。
對一個狀態特別重要的對象,通過狀態機器來建模一個對象的狀態;
狀態模式處理的核心問題是狀態的遷移,因為在對象存在很多狀態情況下,
對各個business flow,各個狀態之間跳轉和遷移過程都是及其複雜的。
例如一個工作流程,審批一個檔案,存在建立、提交、已修改。
HR部門審批中、老闆審批中、HR審批失敗、老闆審批失敗等狀態,涉及多個角色互動,涉及很多事件,
這種情況下用狀態模式(狀態機器)來建模更加合適;
把各個狀態和相應的實現步驟封裝成一組簡單的繼承自一個介面或抽象類別的類,
通過另外的一個Context來操作他們之間的自動狀態變換,通過event來自動實現各個狀態之間的跳轉
參與者:
Context(環境,Person)定義客戶感興趣的類。
State(Moodstate):定義一個介面以封裝與Context的一個特定狀態相關的行為
ConcreteState Subclasses(具體狀態子類,如Angry)每一個子類實現一個與Context的狀態相關的行為。
他們的協作關係是:
Context將於狀態相關的請求委託給當前的ConcreteState對象處理。
Context可將自身作為一個參數傳遞給處理該請求的狀態物件,這使得狀態物件在必要的時候可訪問Context。
Context是客戶使用的主要介面,客戶可用狀態物件來配置一個Context,一旦一個Context配置完畢,他的客戶不再需要直接與狀態物件打交道。
Context或者ConcreteState子類都可以決定哪個狀態是另外那個狀態的後繼者,以及是在何種條件下進行狀態轉換。
Context:
public class Persion {
private MoodState state;
public Persion(){
state = new Mad(this);//開始預設為抓狂狀態
}
public void setState(MoodState state) {
this.state = state;
}
public void request(){
state.doSomething();
state.changeState();
}
}
狀態介面:
public interface MoodState {
public void doSomething();
public void changeState();
}
抓狂狀態:
public class Mad implements MoodState {
Persion persion;
public Mad(Persion persion){
this.persion = persion;
}
public void changeState() {
persion.setState(new Angry(persion));
}
public void doSomething() {
System.out.println("I‘m Mad!");
}
}
生氣狀態:
public class Angry implements MoodState {
Persion persion;
public Angry(Persion persion){
this.persion = persion;
}
public void changeState() {
persion.setState(new Happy(persion));
}
public void doSomething() {
System.out.println("I‘m Angry!");
}
}
高興狀態:
public class Happy implements MoodState {
Persion persion;
public Happy(Persion persion){
this.persion = persion;
}
public void changeState() {
persion.setState(new Mad(persion));
}
public void doSomething() {
System.out.println("I‘m Happy!");
}
}
/**
* 狀態模式
*
* 允許一個對象在其內部狀態改變時改變它的行為,對象看起來似乎修改了它所屬的類
*
*/
interface State
{
public function handle($state);
public function display();
}
class Context
{
private $_state = null;
public function __construct($state)
{
$this->setState($state);
}
public function setState($state)
{
$this->_state = $state;
}
public function request()
{
$this->_state->display();
$this->_state->handle($this);
}
}
class StateA implements State
{
public function handle($context)
{
$context->setState(new StateB());
}
public function display()
{
echo "state A<br/>";
}
}
class StateB implements State
{
public function handle($context)
{
$context->setState(new StateC());
}
public function display()
{
echo "state B<br/>";
}
}
class StateC implements State
{
public function handle($context)
{
$context->setState(new StateA());
}
public function display()
{
echo "state C<br/>";
}
}
// 執行個體化一下
$objContext = new Context(new StateB());
$objContext->request();
$objContext->request();
$objContext->request();
$objContext->request();
$objContext->request();
?>
狀態模式 java && php