Posiadam klasę ActiveRecord BaseModel
i wiele modeli klas, które ją dziedziczą. I mam klasę Bookmark
, która jest również dziedziczona z BaseModel
. Ponadto, mam klasy Decorator
, implementują specjalny interfejs do reprezentowania pojedynczego modelu (metoda getModelView(model)
). To niektóre pseudo-code:Odpowiedni wzorzec dla klasy ActiveRecord
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())
Tak, wszystko wygląda dobrze, dopóki nie chcesz zmieniać tego poglądu na zakładkach modelu nieco. Chcę dodać niestandardowy tytuł do tego widoku. I nie mogę zrobić tego w dekoratorze, ponieważ renderuje to nie tylko na zakładki.
EDYCJA: Problem jest - wydaje mi się, że potrzebuję wzoru dekoratora, ale nie mam nic do odziedziczenia, ponieważ konkretny TestDecorator używa specjalnych metod TestModel. Więc teraz ja zrobiłem jakieś naprawdę złe wykonanie, za pomocą metod magicznych (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];
}
}
tak to będzie działać teraz, ale pod względem struktury kodu, czytelność i stabilność to bardzo zła decyzja.
moi 2cents: Modyfikacja getBookmark(), aby powrócić do modelu z tytułu niestandardowego. Widok to tylko mechanizm renderujący, powinien pozostać ogólny. – lucasg
getBookmark zwraca dowolny model, który dziedziczy po BaseModel. BaseModel ma abstrakcyjną metodę 'getName()'. Zrobiłem coś w rodzaju wzorca dekoratora (ale to nie jest rzeczywisty dekorator, nie mam klasy, z której można dziedziczyć). – UnstableFractal
Teraz myślę o dodaniu 'setName()' do 'BaseModel'. A po prostu ustawienie go w metodzie 'BookmarkModel'' getBookmark' po pobraniu z bazy danych. Myślę, że to łatwiejsza decyzja. Nie sądzę, że będę musiał stawić czoła innej wymaganej funkcjonalności. – UnstableFractal