将持久性添加到MVC模型的最佳实践是什么?

eth*_*ros 4 php model-view-controller frameworks

我正在用PHP实现一个超轻的MVC框架.似乎普遍认为从数据库,文件等加载数据应该独立于模型,我同意.我不确定的是将这个"数据层"链接到MVC的最佳方法.


数据存储与模型交互

//controller
public function update()
{

 $model = $this->loadModel('foo');
 $data = $this->loadDataStore('foo', $model);

 $data->loadBar(9); //loads data and populates Model
 $model->setBar('bar');
 $data->save(); //reads data from Model and saves

}
Run Code Online (Sandbox Code Playgroud)

控制器在模型和数据存储之间进行调解

看起来有点冗长,需要模型知道存在数据存储.

//controller
public function update()
{

 $model = $this->loadModel('foo');
 $data = $this->loadDataStore('foo');

 $model->setDataStore($data);

 $model->getDataStore->loadBar(9); //loads data and populates Model
 $model->setBar('bar');
 $model->getDataStore->save(); //reads data from Model and saves

}
Run Code Online (Sandbox Code Playgroud)

数据存储扩展了Model

如果我们要保存将数据库数据存储扩展到flatfile数据存储区的模型,会发生什么?

//controller
public function update()
{

 $model = $this->loadHybrid('foo'); //get_class == Datastore_Database

 $model->loadBar(9); //loads data and populates
 $model->setBar('bar');
 $model->save(); //saves

}
Run Code Online (Sandbox Code Playgroud)

模型扩展了数据存储区

这允许模型可移植性,但像这样扩展似乎是错误的.此外,数据存储区无法使用任何Model的方法.

//controller extends model
public function update()
{

 $model = $this->loadHybrid('foo');  //get_class == Model

 $model->loadBar(9); //loads data and populates
 $model->setBar('bar');
 $model->save(); //saves

}
Run Code Online (Sandbox Code Playgroud)

编辑:模型与DAO通信

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

//model
public function setBar($bar)
{
    //a bunch of business logic goes here
    $this->dao->setBar($bar);
}

//controller
public function update()
{
    $model = $this->loadModel('foo');
    $model->setBar('baz');
    $model->save();
}
Run Code Online (Sandbox Code Playgroud)

关于"最佳"选项的任何输入 - 或替代 - 都是最受欢迎的.

duf*_*ymo 7

我不认为它属于控制器 - 这实际上是视图的一部分,它可以来来去去.业务逻辑和持久性不应该依赖于视图或控制器.

单独的服务层使您有机会将该逻辑作为分布式组件公开给非基于浏览器的客户端(例如,移动视图,批处理等)

我不希望模型以面向对象的意义扩展数据存储,因为继承是一种IS-A关系.如您所知,该模型不是关系数据库; 这只是众多持久信息中的一种选择.

我认为这是更多的构成.持久层可以是一个单独的DAO,它可以持久化模型对象,而不需要它们知道它们的寿命更长.或者你有mixin行为,其中模型宣告它有CRUD操作的事实,但它只是将请求传递给它们给出的实现.

通常的Spring习语会有一个与控制器分开的服务层.它了解用例和工作单元.它使用模型和持久性对象来实现用例的目标.

MVC意味着三个演员.我想说在典型的应用程序中有更多的层 - 需要添加持久性和服务.

更新:

如果模型对象没有从持久性包中导入任何东西,那么它就不知道它.这是一个简单的例子,使用一个简单的模型类Person及其DAO接口,每个接口都在自己的包中:

package persistence.model;

public class Person
{
    private String name;

    public Person(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,DAO接口导入模型包,但不是相反:

package persistence.persistence;

import persistence.model.Person;

import java.util.List;

public interface PersonDao
{
    Person find(Long id);
    List<Person> find();

    void saveOrUpdate(Person p);
}
Run Code Online (Sandbox Code Playgroud)


eth*_*ros 0

我最终用数据存储类装饰我的模型:

//datastore class
public function __call($name, $arguments)
{

    if (!method_exists($this->model, $name))
        throw new Exception('does not exist!');

    return call_user_func_array(array($this->model, $name), $arguments);

}

//controller - decorating
$model = new Model;
$datastore = new Datastore($model);
$datastore->actions();
Run Code Online (Sandbox Code Playgroud)