0

我正在为一个数据库应用程序开发我自己的 PHP MVC,我已经完成了它,但是使用可以完成所有事情的单片类 - MySQL 处理、输入处理和显示。它工作得很好,但调试和修改是一场噩梦!我最近发现了 MVC,并且正在重写应用程序 - 目前这一切都在绘图板上,所以我实际上没有任何代码可以与您分享。

我遇到了一件事:我知道控制器应该调用模型以根据用户输入对其进行修改,然后调用视图,视图将访问它需要获取其数据的模型和然后显示它。我希望视图独立于控制器获取其数据,而不是让控制器充当中介。我从控制器的那一行开始,从模型中获取数据并将其交给视图,但很快就遇到了麻烦,视图需要访问多个模型。

为了解释我坚持的问题,我将举一个例子:


示例:提交带有数据的表单,模型验证失败

前控制器:

  • 加载相关控制器并调用 ProcessForm 动作

控制器:

  • 实例化 Model 类并调用方法来加载和验证数据

模型:

  • 验证失败:生成错误列表并返回“false”

控制器:

  • 如果模型返回“真”,则重定向到索引页面
  • 它返回'false':调用视图

看法:

  • 实例化 Model 类并获取数据
  • 显示数据和错误消息

我的问题是,拥有自己的模型实例的视图如何获得在控制器的模型实例中生成的错误消息,而控制器没有将自己的模型实例直接交给视图?我认为第一个实例需要将消息存储在第二个实例可以检索它们的地方?

我意识到第一个实例可以将其错误返回给控制器,然后它可以将其传递给视图,独立于模型本身,但我仍然希望保持视图独立于控制器。

4

3 回答 3

2

好吧..所有的拳头,没有“模型”。MVC 和受 MVC 启发的设计模式中的模型是一个,它包含多种结构,就像表示层包含控制器、视图和其他一些东西一样。

除了那部分,您的问题是您拥有这些“模型”的单独实例。相反,控制器和视图都应该共享同一个工厂,该工厂可以生成和缓存实例。

最佳解决方案是让您拥有服务,这些服务代表模型层的一部分,控制器和视图通过这些服务与模型交互。工厂会在被请求时第一次初始化服务,然后在任何重复请求时提供相同的实例。

class ServiceFactory
{
    private $cache = array();

    public function create( $name )
    {
        if ( array_key_exists($name, $this->cache) === false )
        {
            $this->cache[$name] = new $name;
        }
        return $this->cache[$name];
    }
}

这是服务工厂的“极其愚蠢”的版本。

在引导阶段,您初始化服务工厂,然后通过将其注入所述实例的构造函数中,为当前控制器和当前视图提供它的实例。

于 2013-04-07T20:55:22.593 回答
2

首先,控制器和视图不应该有不同的模型实例。他们都应该使用相同的实例。在这种结构中划分你的类更实用。

领域类(模型)

域类只是保存数据以提供上下文。例如,您可以有一个Person域类。

class Person {
    private $name;
    private $age;
    ...
    public function getName()
    public function getAge()
    ...
}

控制器

控制器是模型和视图之间的桥梁。它们不应包含任何业务逻辑。这就是服务的用途。

class PersonController
{
    private personService;

    public function list(Bag bag) {
        bag.add('personList', personService.listAll());
        ...
        Give bag of data to the correct view
        ...
    }
}

服务

服务处理应用程序逻辑。主要是包含域逻辑和存储抽象的实体之间的交互。

class PersonService {
    public function listAll() {
        ...
        Do the logic to find all persons
        ...
        return $persons;
    }
}

意见

视图只显示控制器提供给它们的数据。它没有自己的模型。


它不能解决所有问题,但至少它是让你的结构正确的一个不错的开始。

Spring Framework (Java) 有一个非常好的 MVC 实现。见灵感http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html

于 2013-04-07T21:12:02.120 回答
0

无需控制器将自己的模型实例直接交给视图

为什么?这是正常发生的事情,这可能也是你应该做的。模型实例可以在内部存储验证错误,如果控制器将相同的实例传递给视图,那么如何传播此信息的问题就会自行解决。

于 2013-04-07T20:55:11.897 回答