2016-03-21 9 views
2

私はPHPでState-Machineデザインパターンを実装しようとしています。プログラムは、状態遷移について知っているラッパーオブジェクトに対してメソッド呼び出しを行います。状態オブジェクトは動作を実行するが、各状態オブジェクトは、状態の利用可能な方法と一致する異なるインタフェースを有する。これは、関数をカプセル化するために行われます。そのため、オブジェクトは、管理不能なオブジェクトであるため、オブジェクトが存続期間中に実行可能なすべてのアクションに対してメソッド定義を持つ必要はありません。私はparticlar状態にあるオブジェクトを記述するためにタイプヒンティングを使用する方法にStatefulObjectを渡すしようとすると、PHP:実行時にInterfaceをどのように偽装できますか?

//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(...){ ... } 
} 

問題はその後、到着しました。たとえば、メソッドsomeMethod(State2 $obj)を使用したい場合は、StatefulObjectを渡すことができるようにするには、保持できるすべてのオブジェクト状態内で処理されるすべてのメソッドの定義をStatefulObjectに渡す必要はありません。

StatefulObjectは、その中に含まれるオブジェクトのインタフェースを実装していますが、PHPはこれを見ていないだろうし、現在State2オブジェクトを保持StatefulObjectsomeMethodに渡された場合に例外をスローしていました。どのように私は動的にシステムのコンポーネントに錯覚を提供できますか?

+0

インターフェイスにヒントを入力する必要があります。それが何らかの理由で動作しない場合は、 '__call()'の最初に独自の型チェックロジックを実装することができます –

+0

あなたは精巧にできますか? –

答えて

0

答えは、デザインパターンの変更にあるようです。 StatefulObjectに状態を格納する代わりに、StatefulObjectではなくStateに基づいてStatefulObjectをラップして使用します。

私の現在のシステムでは、State Design Patternに対するハイブリッドアプローチが採用されていますが、インターフェースは同じですが、動作が変わったときにStatefulオブジェクトを渡し、状態を実行します。インターフェイスが異なる必要がある場合は、代わりに状態を渡します。状態はオブジェクトを参照し、オブジェクトは状態を参照します。状態1によって提供される方法を必要

enter image description here

方法は、被検体内部それに運ぶ状態1オブジェクトを受け取ります。より汎用的なインタフェースを必要とするメソッドはStatefulObjectに渡され、StatefulObjectにはその状態が渡されます。それがシステムを通過するとき、それはほぼMobiusに似ています。その内部は、その瞬間の目的を何度も繰り返しています。

関連する問題