Ich versuche, ein State-Machine-Entwurfsmuster in PHP zu implementieren. Das Programm führt einen Methodenaufruf für ein Wrapper-Objekt aus, das Zustandsübergänge kennt. Das Statusobjekt führt die Aktion aus, aber jedes Statusobjekt verfügt über eine andere Schnittstelle, die den verfügbaren Methoden des Status entspricht. Dies geschieht, um eine Funktion zu kapseln, so dass das Objekt keine Methodendefinition für jede mögliche Aktion haben muss, die an dem Objekt während seiner Lebenszeit ausgeführt werden kann, da dies ein nicht handhabbares Objekt wäre.PHP: Wie kann man ein Interface zur Laufzeit fälschen?
//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(...){ ... }
}
Das Problem kommt dann, wenn ich versuche, ein StatefulObject
in eine Methode zu übergeben, Type Hinting verwendet ein Objekt zu beschreiben, die in einem particlar Zustand befindet. Wenn ich zum Beispiel eine Methode someMethod(State2 $obj)
haben möchte, möchte ich die StatefulObject
übergeben können, ohne der StatefulObject
eine Definition für jede Methode geben zu müssen, die in allen Objektzuständen gehandhabt wird, die sie halten kann.
Die StatefulObject
implementiert die Schnittstelle des Objekts in ihm enthalten ist, aber PHP wäre dies nicht sehen und eine Ausnahme auslösen würde, wenn die StatefulObject
derzeit ein State2
Objekthalte waren in someMethod
weitergegeben werden. Wie kann ich den Systemkomponenten dynamisch eine Schnittstellenillusion geben?
Sie sollten in der Lage sein, die Schnittstelle einzugeben. Wenn das aus irgendeinem Grund nicht funktioniert, können Sie immer Ihre eigene Typ-Check-Logik am Anfang von '__call()' implementieren. –
Könnten Sie das näher erläutern? –