我正在为数据库应用程序开发自己的PHP MVC,我已经完成了但是使用了可以完成所有工作的单片类 - MySQL处理,输入处理和显示。它工作得很好,但调试和改变是一个噩梦!我最近发现了MVC并且在重写应用程序的过程中 - 目前所有这些都在绘图板上,所以我实际上没有任何代码可以与你分享。
有一件事我磕磕绊绊:我已经知道Controller应该调用Model来根据用户输入修改它,然后调用View,它将访问它需要得到的模型它的数据,然后显示它。我希望视图能够独立于Controller获取其数据,而不是让Controller充当中介。我开始从控制器的那一行获取模型中的数据并将其交给View,但很快遇到了View需要访问多个模型的麻烦。
为了解释我所坚持的内容,我将举一个例子:
示例:提交包含数据的表单,但未通过模型验证
前控制器:
控制器:
型号:
控制器:
查看:
我的问题是,具有自己的Model实例的View如何获取在Controller的模型实例中生成的错误消息,而Controller不会将自己的Model实例直接交给视图?我想第一个实例需要将消息存储在第二个实例可以检索它们的地方吗?
我意识到第一个实例可以将其错误返回给Controller,然后它可以传递给视图,与模型本身无关,但我仍然希望保持View独立于Controller。
答案 0 :(得分:2)
嗯..所有的拳头,没有“模特”。 MVC和MVC启发的设计模式中的模型是layer,它包含大量结构,就像表示层包含控制器,视图和其他一些东西一样。
除此之外,您的问题是您拥有这些“模型”的单独实例。相反,控制器和视图应该共享相同的工厂,这可以生成和缓存实例。
最佳解决方案是为您提供服务,这些服务代表模型层的一部分,控制器和视图通过这些服务与模型交互。工厂会在请求时首次初始化服务,然后在任何重复请求时提供相同的实例。
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];
}
}
这是服务工厂的“非常愚蠢”版本。
在引导阶段,初始化服务工厂,然后通过将其注入所述实例的构造函数中,为当前控制器和当前视图提供实例。
答案 1 :(得分: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
答案 2 :(得分:0)
没有Controller将自己的Model实例直接交给View
为什么呢?这就是正常情况,这可能也是你应该做的。模型实例可以在内部存储验证错误,如果控制器将相同的实例传递给视图,则如何传播此信息的问题将自行解决。