Ich benutze das Designmuster Decorator in PHP, und ich habe ein Strukturproblem.Decorator Muster mit Methodenrelation
Hier ist ein einfaches Beispiel, mein Problem zu veranschaulichen:
interface MyInterface {
function showUsers($array);
function showUser($i);
}
class MyCLass implements MyInterface {
function showUsers($array)
{
foreach($array as $toto) {
$this->showUser($toto);
}
}
function showUser($i)
{
echo $i;
}
}
class MyCLassDecorator implements MyInterface {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUsers($array)
{
$this->inner->showUsers($array);
}
function showUser($i)
{
echo "User: $i";
}
}
class MyCLassDecorator2 implements MyInterface {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUsers($array)
{
$this->inner->showUsers($array);
}
function showUser($i)
{
$this->inner->showUser($i);
echo " is wonderful";
}
}
$myClass = new MyCLassDecorator2(new MyCLassDecorator(new MyCLass()));
$myClass->showUsers(["Alfred", "Bob", "Claire"]);
Mit diesem Code der Methoden von MyClassDecorator & showuser MyClassDecorator2 wird nie aufgerufen werden.
Was kann ich tun? Ist es verboten, eine andere Methode derselben Klasse aufzurufen? (Nicht wirklich praktisch, meinen Code zu teilen) Gibt es eine andere Möglichkeit, dies zu tun? Sollte ich eine Schnittstelle nach Methode erstellen?
Vielen Dank :)
EDIT:
Hier ist die Lösung, die ich schließlich verwendet, obwohl ich es nicht wirklich zufrieden bin ...
ich meinen Code aufgespalten nicht in Methoden, aber in Schnittstellen (Dienste)
Hier ist sie:
interface IShowUsers {
function showUsers($array);
}
interface IShowUser {
function showUser($user);
}
class Services {
static $showUsers;
static $showUser;
}
class MyShowUsers implements IShowUsers {
function showUsers($array)
{
foreach($array as $toto) {
Services::$showUser->showUser($toto);
}
}
}
class MyShowUser implements IShowUser {
function showUser($user)
{
echo $user;
}
}
class MyShowUserDecorator implements IShowUser {
private $inner;
public function __construct(IShowUser $inner)
{
$this->inner = $inner;
}
function showUser($user)
{
echo "User: ";
$this->inner->showUser($user)
}
}
class MyShowUserDecorator2 implements IShowUser {
private $inner;
public function __construct(MyInterface $inner)
{
$this->inner = $inner;
}
function showUser($user)
{
$this->inner->showUser($user);
echo " is wonderful";
}
}
$myClass = new MyShowUserDecorator2(new MyShowUserDecorator(new MyShowUser()));
Services::$showUsers = new MyShosUsers();
Services::$showUser = new MyShowUserDecorator2(new MyShowUserDecorator(new MyShowUser()));
Services::$showUsers->showUsers(["Alfred", "Bob", "Claire"]);
Wenn Sie eine bessere Lösung haben, werde ich glücklich sein es
Natürlich, ich benutze die Decorator-Muster wie diese Dekorateure in unterschiedlicher Weise in vielen Projekten zu nutzen zu wissen :) in diesem exemples:
//no decorators
Services::$showUser = new MyShowUser();
//only the first
Services::$showUser = new MyShowUserDecorator(new MyShowUser());
//only the second
Services::$showUser = new MyShowUserDecorator2(new MyShowUser());
So scheint die Erweiterung keine gute Lösung zu sein.
Vielen Dank noch einmal für die richtige Art und Weise zu geben, dies zu tun :)
Ja, in diesem kleinen Beispiel wäre es ein guter Weg, um es zu beheben, aber ich habe dieses Problem in Symfony Services mit viel komplexere Funktionen und mehr Dekoration Kapselung. Also muss ich das Decorator-Muster beibehalten, um zu vermeiden, dass die Overridings gelöscht werden. –
Sie verwenden das Dekorationsmuster nicht korrekt und Sie haben Ihren Code bearbeitet, sodass mein Beispiel jetzt veraltet ist. Sie rufen '$ this-> inner-> showUsers ($ array);' das 'showUsers' für eine Instanz von' MyCLass' aufruft, deshalb verwendet es 'MyCLassDecorator :: showUser' nicht.Sie müssen entweder die Klasse "erweitern", damit sie über Methoden informiert, die überschrieben werden, oder Sie müssen das Dekoratormuster korrekt verwenden. Ich werde sehen, ob ich ein Beispiel finden kann. – waterloomatt
Ich habe meinen Beitrag bearbeitet, du wirst jetzt vielleicht besser verstehen, was ich brauche :) Und ich präzis, dass ich vorher nicht weiß, in welcher Reihenfolge die Dekorateure verwendet werden. –