Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 改进MVC的使用_Php_Model View Controller_Viewmodel_Dry - Fatal编程技术网

Php 改进MVC的使用

Php 改进MVC的使用,php,model-view-controller,viewmodel,dry,Php,Model View Controller,Viewmodel,Dry,我正忙于使用Kohana MVC框架在PHP中构建一个MVC应用程序,它运行得非常好。但是有一些小麻烦我想解决 许多逻辑在控制器中的操作和控制器本身之间重复。我一直在考虑这个问题,我认为定义一个包含这个共享逻辑的对象是明智的,这样就不会重复了 然后我在一些播客上听到了视图模型。所以视图模型就是我想要的 但是现在问题来了,你在视图模型中放了什么。我的想法是让视图模型收集相应视图所需的所有信息。这样做的好处是,每个控制器/操作只需要将输入数据传递给视图模型,然后再传递给视图 这是个聪明的主意吗?在测

我正忙于使用Kohana MVC框架在PHP中构建一个MVC应用程序,它运行得非常好。但是有一些小麻烦我想解决

许多逻辑在控制器中的操作和控制器本身之间重复。我一直在考虑这个问题,我认为定义一个包含这个共享逻辑的对象是明智的,这样就不会重复了

然后我在一些播客上听到了视图模型。所以视图模型就是我想要的

但是现在问题来了,你在视图模型中放了什么。我的想法是让视图模型收集相应视图所需的所有信息。这样做的好处是,每个控制器/操作只需要将输入数据传递给视图模型,然后再传递给视图

这是个聪明的主意吗?在测试行为上,将模型传递给viewmodel是明智的,这样就可以模拟它。但我并没有真正使用模型。相反,我让控制器通过ORM访问数据库。将每个查询转换为单独的方法似乎有点尴尬,但可能我遗漏了一些东西

据我所知,视图模型只是普通的DTO。但是在动态弱类型语言中,这有什么好处呢

也许我完全走错了方向,应该做得与众不同。你对此有什么想法

编辑:

我所说的大部分逻辑是收集正确的信息并将其传递给正确的视图

例如:


我有一个客户控制员。这有两个操作:添加和编辑。对于这两个操作,我使用相同的视图。在这两个操作中,为视图指定了相同的变量。在add操作中,当表单无效时,输入变量将再次传递给视图。在“编辑”操作中,现有值将通过。这是一个巨大的重复,我想指出。

重复的逻辑表明需要进行一些重构,你不说loic是什么,所以我们不能确定你将它重构到哪里,但不要重复你自己是一个有用的原则。所以最初的想法是好的。我想知道您从控制器到数据库的直接交互(即缺少模型)是否是复制的部分原因


视图模型不仅仅是DTO。它们包含(或指向)业务数据,并且还具有相关的解释逻辑。在你提到的“任务爬行”一文中,你看到了这个想法。视图本身想知道是否显示链接。该决策基于各种业务数据。您可以在一个简单的showLink()方法中组合该逻辑。然后视图可以聚焦于表示,视图模型可以聚焦于解释。而且,同样重要的是,实际的业务数据本身并不知道该演示文稿。

解决您在前面段落中对控制器中重复代码的担忧。。。对于Kohana,我通常将公共控制器代码放在基本控制器中,并从中继承所有控制器

例如,在一个项目中,我使用一个修改过的Template_Controller版本,以$this->Auth的形式引用每个页面上的Auth模块

abstract class Template_Controller extends Controller {

    /* @var Auth_Core reference to authorization class */
    protected $auth;

    public function __construct()
    {
        parent::__construct();
        [snip]
        $this->auth = new Auth();
    }
[...]
}
现在我所有的控制器都是这样开始的:

class Help_Controller extends Template_Controller {

因此,所有控制器都可以在任何函数中访问$this->auth。同意将商业逻辑排除在视图之外,这就是全部想法。

我已经有了这样的设置。我有一个扩展模板控制器的应用程序控制器。每个其他控制器扩展应用程序控制器。这么多的共享逻辑已经集中在一个地方了。对不起,我不理解添加和编辑之间的重复,听起来代码并不完全一样