2013-04-29 25 views
15

Tôi có lớp ActiveRecord BaseModel và rất nhiều lớp học-mô hình kế thừa từ đó. Và tôi đã có một lớp học Bookmark, được thừa hưởng từ số BaseModel. Ngoài ra, tôi đã có Decorator lớp được thừa kế, chúng thực hiện giao diện đặc biệt để biểu diễn mô hình đơn lẻ (phương pháp getModelView(model)). Đây là một số mã giả:Mẫu thích hợp cho lớp 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()) 

Vì vậy, mọi thứ có vẻ tốt, cho đến khi tôi muốn thay đổi Chế độ xem cho mô hình được đánh dấu một chút. Tôi muốn thêm tiêu đề tùy chỉnh cho chế độ xem đó. Và tôi không thể làm cho nó bên trong trang trí, bởi vì nó làm cho nó không chỉ cho một dấu trang.

EDIT: Vì vậy, vấn đề là - có vẻ như tôi cần một mẫu trang trí, nhưng tôi không có bất cứ điều gì để kế thừa từ, bởi vì TestDecorator cụ thể bằng cách sử dụng phương pháp speical TestModel. Vì vậy, bây giờ tôi đã thực hiện một số thực hiện thực sự xấu, sử dụng phương pháp kỳ diệu (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]; 
    } 

} 

Vì vậy, nó sẽ làm việc cho bây giờ, nhưng về mặt cấu trúc mã, dễ đọc và ổn định đó là quyết định thực sự tồi tệ.

+0

2cents tôi: sửa đổi getBookmark() để trả lại mô hình với tiêu đề tùy chỉnh. Chế độ xem chỉ là trình kết xuất đồ họa, nó sẽ vẫn giữ nguyên. – lucasg

+0

getBookmark trả về bất kỳ mô hình nào, được kế thừa từ BaseModel. BaseModel có phương thức trừu tượng 'getName()'. Tôi đã thực hiện một số loại một mẫu Decorator (nhưng nó không phải là trang trí thực tế, tôi không có một lớp kế thừa từ.) – UnstableFractal

+0

Bây giờ tôi đang suy nghĩ về việc thêm 'setName()' vào 'BaseModel'. Và chỉ cần thiết lập nó trong phương thức 'BookmarkModel'' getBookmark' sau khi lấy nó từ cơ sở dữ liệu. Tôi nghĩ rằng đó là quyết định dễ dàng hơn. Tôi không nghĩ rằng tôi sẽ phải đối mặt với bất kỳ chức năng cần thiết nào khác. – UnstableFractal

Trả lời

2

Mô hình không nên biết về chế độ xem. Các mô hình đại diện cho dữ liệu thô được nhìn thấy từ mọi góc cùng một lúc. Chế độ xem là góc nhìn của mô hình đó. Bộ điều khiển nên ăn các mô hình để quan điểm:

$model_view->render($model); 

Sau đó trang trí xem:

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

Chỉ trang trí dựa trên giao diện, chứ không phải các loại.

Phương pháp ma thuật của PHP rất tuyệt, nhưng chúng không được sử dụng cho ActiveRecord, điều này đi ngược lại "tách mối quan tâm", trong trường hợp này tách mô hình khỏi cơ chế kiên trì.

Thay vào đó, hãy tạo đối tượng ActiveRecord và cấp mô hình đến.

$record->store($model); 

Sau đó, nếu bạn cần phải sửa đổi lưu trữ, một lần nữa chỉ cần trang trí cơ chế lưu trữ:

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

Trường hợp này chính xác như thế nào với việc tách mô hình khỏi cơ chế bền vững? Về cơ bản, tôi không thấy bất kỳ lợi thế nào. – UnstableFractal

+0

Điểm đầu tiên là một ví dụ về trang trí phù hợp, nghĩa là, chỉ trang trí các giao diện và tách mô hình khỏi chế độ xem. Điểm thứ hai là minh họa rằng tạo ra đối tượng chính nó cơ chế lưu trữ giới thiệu một sự phức tạp có quy mô với độ phức tạp của đối tượng của bạn và không dễ dàng hoán đổi hoặc _unit testable_, như được minh chứng bằng cách cố gắng gói đối tượng của bạn. Bạn sẽ làm tốt hơn để làm cho BookmarkedModel trở thành một phần mở rộng của BaseEntityModel. –

+0

Mô hình chỉ nên quan tâm xem chúng có đang ở trạng thái hợp lệ hay không. Đó là mục đích của họ. Không phải để tồn tại. –

Các vấn đề liên quan