2013-04-29 7 views
15

Bir ActiveRecord BaseModel sınıfım var ve onlardan devralan bir çok sınıf modeli var. Ve Bookmark sınıfına da sahibim, bu da BaseModel'dan miras alınmış. Ayrıca, ben Decorator -inherited sınıfları var, onlar tek bir model (getModelView(model) yöntemi) temsil etmek için özel bir arabirim uygular. i Yerimlerine modeli biraz söz konusu Görünümü değiştirmek istediğiniz kadarActiveRecord sınıfı için uygun desen

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()) 

Böylece, her şey iyi görünüyor: Bu, bazı sözde koddur. Bu görünüm için özel bir başlık eklemek istiyorum. Ve bunu dekoratörün içinde yapamıyorum çünkü sadece bir yer imleri için değil.

DÜZENLEME: Yani, problem - bir dekoratör paternine ihtiyacım var gibi görünüyor, ama ben TestModel speical yöntemlerini kullanarak beton TestDecorator, çünkü miras almak için bir şey yok. Yani şimdi ben sihirli yöntemler (PHP) kullanarak, bazı gerçekten kötü gerçekleşmesini yaptık: Yani şimdilik çalışacak

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]; 
    } 

} 

ancak kod yapısı, okunabilirliği ve istikrar açısından gerçekten kötü bir karar.

+0

benim 2cents: getBookmark değiştirmek() özel başlığı ile bir model geri verilmesi gereken depolama değiştirmek gerekiyorsa

$record->store($model); 

Sonra yine sadece depolama mekanizması süsleyin. Görünüm sadece bir işleyicidir, jenerik kalmalıdır. – lucasg

+0

getBookmark, BaseModel'den gelen herhangi bir modeli döndürür. BaseModel 'getName() 'soyut yöntemine sahiptir. Bir çeşit dekoratör deseni yaptım (ama gerçek dekoratör değil, miras alacağım bir dersim yok.) – UnstableFractal

+0

Şimdi 'baseModel' öğesine setName() 'yi eklemeyi düşünüyorum. Ve veritabanından aldıktan sonra 'BookmarkModel'' getBookmark' yönteminde ayarlayarak. Bence daha kolay karar. Başka gerekli işlevsellikle karşılaşacağımı sanmıyorum. – UnstableFractal

cevap

2

Model, görüntünün farkında olmamalıdır. Modeller, her açıda görülen ham verileri bir kerede temsil eder. Görünüm, bu modelin perspektif perspektifidir. Kontrolör görünümü modeli beslemek gerekir:

$model_view->render($model); 

Sonra görünümü süslemek:

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

Sadece arayüzleri değil, türleri dayalı süslemeleri.

PHP'nin sihirli yöntemleri harika, ancak bunlar ActiveRecord için kullanılmamalıdır, bu durum "endişelerin ayrılması" na karşı gelir, bu durumda modeli kalıcılık mekanizmasından ayırır. Bunun yerine, bir ActiveRecord nesnesi yapın ve modelini için besleyin.

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

Bu durum tam olarak nasıl modelin kalıcılık mekanizmasından ayrılmasında yardımcı olur? Temel olarak, hiçbir avantaj görmüyorum. – UnstableFractal

+0

İlk nokta uygun bir dekorasyon örneğidir, yani sadece arayüzlerin dekorasyonudur ve modeli görünümden ayırır. İkinci nokta, nesneyi kendisinin depolama mekanizmasının nesnenizin karmaşıklığı ile ölçeklendiren bir karmaşıklığı ortaya koyduğunu ve nesneyi sarmalama girişimi ile gösterildiği gibi kolayca test edilemediğini veya tesle_kullanılmadığını göstermektir. BookmarkedModel'i BaseEntityModel'in bir uzantısı yapmak için daha iyisini yaparsınız. –

+0

Modeller yalnızca geçerli bir durumda olup olmadıklarına dikkat etmelidir. Bu onların amacı. Kendilerini ısrar etmemek. –