私は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
オブジェクトを保持StatefulObject
がsomeMethod
に渡された場合に例外をスローしていました。どのように私は動的にシステムのコンポーネントに錯覚を提供できますか?
インターフェイスにヒントを入力する必要があります。それが何らかの理由で動作しない場合は、 '__call()'の最初に独自の型チェックロジックを実装することができます –
あなたは精巧にできますか? –