php - ActiveRecord 类的适当模式

标签 php oop activerecord

我有一个 ActiveRecord BaseModel 类和许多从它继承的类模型。我还有一个 Bookmark 类,它也是从 BaseModel 继承的。 此外,我还有 Decorator 继承类,它们实现了特殊的接口(interface)来表示单个模型(getModelView(model) 方法)。这是一些伪代码:

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

所以,一切看起来都不错,直到我想稍微更改一下带有书签的模型的 View 。我想要为该 View 添加自定义标题。而且我无法将它放在装饰器中,因为它不仅为书签呈现它。

编辑:所以,问题是 - 似乎我需要一个装饰器模式,但我没有任何东西可以继承,因为具体的 TestDecorator 使用 TestModel 特殊方法。所以现在我使用魔术方法 (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];
    }

}

所以它现在可以工作,但就代码结构、可读性和稳定性而言,这是一个非常糟糕的决定。

最佳答案

模型应该不知道 View 。模型代表一次从各个角度看到的原始数据。 View 是该模型的视角。 Controller 应该将模型提供给 View :

$model_view->render($model);

然后装饰 View :

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

只根据接口(interface)而不是类型进行装饰。

PHP 的魔术方法很棒,但它们不应该用于 ActiveRecord,这违背了“关注点分离”,在这种情况下将模型与其持久性机制分开。

而是制作一个 ActiveRecord 对象并将模型提供给它。

$record->store($model);

然后如果你需要修改存储,再次装饰存储机制:

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

关于php - ActiveRecord 类的适当模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16277088/

相关文章:

oop - Vo 代表什么?

mysql - 数据库 :seed not loading models

ruby-on-rails - 如何递增属性,使其值(至少)比其他记录高 1 并且唯一

php - 根据广播选择要显示的字段

php - 如何使用 Netbeans 调试 Symfony3?

java - 如何使用构造函数设置不在构造函数内部的其他字段

language-agnostic - 在构造函数中立即采取行动有什么问题吗?

php - SQL中的条件表达式

php - mysql查询获取多行的多个附件

java - 停留在 Java 中的对象范围