2013-04-29 12 views
15

Ich habe eine ActiveRecord BaseModel Klasse und viele Klassen-Modelle, die davon erben. Und ich habe eine Klasse Bookmark, die von BaseModel geerbt wird. Ich habe auch Decorator -inherited Klassen, sie implementiert spezielle Schnittstelle, um einzelnes Modell (getModelView(model) Methode) darzustellen. Dies ist einige Pseudo-Code:Geeignetes Muster für ActiveRecord Klasse

TestModel inherits BaseModel 
    getName: 
     return this.name 

BookmarkModel inherits BaseModel 
    BaseModel model 

    getBookmark: 
     return this.model 

TestDecorator inherits BaseDecorator implements SingleModelViewInterface: 
    getView(model): 
     return 'view' //html-view of model 

BookmarkDecorator inherits BaseDecorator 
    getBookmarksView(BookmarkModel[] bookmarks): 
     foreach(bookmarks > bookmark): 
      decorator = Relation::getDecoratorByModel(bookmark->getEntityType()) 
      decorator->getView(bookmark->getBookmark()) 

Also, alles sieht gut aus, bis ich für Markiert Modell ein wenig, dass die Ansicht ändern möchten. Ich möchte einen benutzerdefinierten Titel für diese Ansicht hinzufügen. Und ich kann es innen nicht schaffen, weil es es nicht nur für ein Lesezeichen macht.

EDIT: Also, das Problem ist - scheint, dass ich ein Dekorator Muster brauche, aber ich habe nichts zu erben, weil konkrete TestDecorator TestModel speical Methoden verwenden. So, jetzt habe ich einige wirklich schlechte Realisierung getan, magische Methoden (PHP):

class BookmarkedModel { 

    /** @var BaseEntityModel*/ 
    private $model; 

    public function __construct(BaseEntityModel $model) { 
     $this->model = $model; 
    } 

    public function getName() { 
     return 'Bookmark '.$this->model->getName(); 
    } 

    public function __call($name, $arguments) { 
     return call_user_func_array(array($this->model, $name), $arguments); 
    } 

    public function __get($name) { 
     return $this->model->$name; 
    } 

    public function __set($name, $value) { 
     return $this->model->$name[$value]; 
    } 

} 

So wird es für jetzt arbeiten, aber in Bezug auf die Code-Struktur, Lesbarkeit und Stabilität ist es wirklich schlechte Entscheidung.

+0

meine 2cents: modifizieren GetBookmark() das Modell mit dem benutzerdefinierten Titel zurückzukehren. Die Ansicht ist nur ein Renderer und sollte generisch bleiben. – lucasg

+0

getBookmark gibt jedes Modell zurück, das von BaseModel erbt. BaseModel hat die abstrakte Methode 'getName()'. Ich habe irgendeine Art von Decorator-Muster gemacht (aber es ist nicht der eigentliche Dekorator, ich habe keine Klasse, von der ich erben könnte.) – UnstableFractal

+0

Jetzt denke ich darüber nach, 'setName()' zu 'BaseModel' hinzuzufügen. Und setzen Sie es einfach in 'BookmarkModel'' getBookmark' Methode nach dem Abrufen aus der Datenbank. Ich denke, es ist einfacher Entscheidung. Ich glaube nicht, dass ich mit einer anderen erforderlichen Funktionalität konfrontiert werde. – UnstableFractal

Antwort

2

Das Modell sollte sich der Ansicht nicht bewusst sein. Modelle repräsentieren die Rohdaten aus jedem Blickwinkel gleichzeitig. Die Ansicht ist eine Perspektive dieses Modells. Die Steuerung sollte das Modell füttern die Ansicht:

$model_view->render($model); 

dann die Ansicht dekorieren:

$bookmark_view->render($model); // bookmark_view wraps a model_view, 
// returns 'Bookmark '.$this->model_view->render($model) 

Nur basierend auf Schnittstellen Dekoration, keine Typen.

Die magischen Methoden von PHP sind großartig, aber sie sollten nicht für ActiveRecord verwendet werden, was gegen die "Trennung von Belangen" steht und in diesem Fall das Modell von seinem Persistenzmechanismus trennt.

Erstellen Sie stattdessen ein ActiveRecord-Objekt und führen Sie das Modell zu es.

$record->store($model); 

Dann, wenn Sie Speicher ändern müssen, wieder dekorieren nur den Speichermechanismus:

$log_record->store($model); // wraps $record, logs a message prior to database storage. 
+0

Wie genau hilft dieser Fall, das Modell vom Persistenzmechanismus zu trennen? Grundsätzlich sehe ich keine Vorteile. – UnstableFractal

+0

Der erste Punkt ist ein Beispiel für die richtige Dekoration, das heißt, nur die Dekoration von Interfaces und die Trennung des Modells von der Ansicht. Der zweite Punkt besteht darin, zu veranschaulichen, dass das Objekt selbst zum Speichermechanismus wird, der eine Komplexität einführt, die mit der Objektkomplexität skaliert und nicht einfach ausgelagert oder testbar gemacht werden kann, wie der Versuch zeigt, Ihr Objekt zu umhüllen. Es wäre besser, BookmarkedModel zu einer Erweiterung von BaseEntityModel zu machen. –

+0

Modelle sollten nur darauf achten, ob sie sich in einem gültigen Zustand befinden. Das ist ihr Zweck. Nicht um sich zu behaupten. –

Verwandte Themen