2016-03-21 19 views
2

我想在PHP中實現一個狀態機設計模式。該程序在知道狀態轉換的包裝器對象上進行方法調用。狀態對象執行動作,但每個狀態對象都有一個與狀態的可用方法相匹配的不同接口。這樣做是爲了封裝函數,以便對象不需要爲在對象的整個生命週期內對對象執行的每個可能的操作都有一個方法定義,因爲這將是一個難以管理的對象。PHP:在運行時如何僞造一個接口?

//Psuedo-code: 
class StatefulObject{ 
    protected $state; 
    /* the dynamically set state order prevents us from having 
    * to give states knowledge of eachother. 
    */ 
    protected $dynamicallySetStateOrder; 
    public function __call($name, $arguments){ 
     /* 
     * we pass all method calls to the state object 
     * the state object performs the action on the 
     * StatefulObject 
     */ 
     if(method_exists($this->state, $name)){ 
      $this->state->$name($arguments); 
     } 
    } 
} 
interface StateInterface{ 
    public function setStatefulObject($obj); 
    /* 
    * a state does not know about states before and after, but it 
    * knows if an object meets the prerequisites to enter its own 
    * state 
    */ 
    public function willAcceptStatefulObject($obj); 
} 
class State1 implements StateInterface{ 
    public function action1(...){ ... } 
    public function action2(...){ ... } 
    public function action3(...){ ... } 
    ... 
    public function action99(...){ ... } 
} 
class State2 implements StateInterface{ 
    public function actionA(...){ ... } 
    public function actionB(...){ ... } 
    ... 
    public function actionZ(...){ ... } 
} 

問題然後當我嘗試一個StatefulObject傳遞到使用類型提示來描述一個對象,它是在particlar狀態的方法到達。例如,如果我希望有一個方法someMethod(State2 $obj),我希望能夠傳入StatefulObject,而不必爲StatefulObject定義在其可以容納的所有對象狀態中處理的每個方法的定義。

StatefulObject實現它所包含的對象的接口,但是PHP就不會看到這一點,如果StatefulObject目前持有State2對象將被傳遞到someMethod會拋出異常。我如何動態地爲系統組件提供界面錯覺?

+0

您應該可以鍵入提示界面。如果由於某種原因無法正常工作,你可以在'__call()' –

+0

的開頭實現自己的類型檢查邏輯,你可以詳細說明一下嗎? –

回答

0

答案似乎是在改變設計模式。現在,我不是將狀態存儲在StatefulObject中,而是將StatefulObject包裝在狀態中,並使用基於狀態而不是StatefulObject的類型提示。

我目前的系統現在有一個混合的方法來狀態設計模式,當接口保持不變,但行爲改變時,我通過StatefulObject並調用狀態的方法來執行操作。當接口需要不同時,我改爲傳遞狀態。狀態指的是對象,而對象則指向狀態。需要由狀態1所提供的方法

enter image description here

方法接收一個狀態1對象,這與它在對象內部進行。需要更通用接口的方法傳遞給StatefulObject,並且StatefulObject攜帶狀態。當它通過系統時,它幾乎就像是一個莫比烏斯:它的內部一次又一次地成爲它的外部以滿足當下的目的。