MVC&计划国家 - 模特应该愚蠢吗?

时间:2011-01-28 15:44:51

标签: php model-view-controller session-variables paradigms

我正在使用一个使用MVC范例的框架。它是CodeIgniter,但我的问题不是专门针对框架 - 更常见的是关于使用MVC时的最佳实践。

我正在使用$ _SESSION变量来维护一些状态变量(用户选择,一些临时首选项,一些数据过滤选项)。这很容易做到,但我发现我在两个模型和控制器之间分配这些变量的使用。有时我会在控制器中更新一个,并在模型中查找。这开始“闻”有趣,因为在我看来,让模型“意识到”所有这些设置可能不是一个好主意。模型不应该只接受获取/操作数据的请求,而只关心请求中明确的内容(不必查找外部变量)吗?

以下是一个示例:我有一个名为$ _SESSION ['regionFilter']的会话变量。这是在控制器中创建和更新的,代表用户想要“向下钻取”的销售区域。当控制器从模型请求某些数据时,我当前让模型查找$ _SESSION ['regionFilter']变量,并在为数据库创建SQL时使用它。似乎让模型对程序状态“哑”更有意义,并让控制器以某种方式将$ _SESSION ['regionFilter']变量捆绑到其请求中,如果它需要它。

有什么想法?谢谢!


编辑:感谢您的讨论,伙计们。我知道重叠的问题,但很难找到关于这个主题的一般性讨论 - 我对“MVC模型程序状态”的搜索发现了一些关于ASP.NET-MVC特定讨论的问题,这些问题在实现中陷入困境的信息。

我已将问题标记为已关闭。再次感谢您的想法!

3 个答案:

答案 0 :(得分:4)

我觉得你很担心它闻起来很有趣。您刚刚在模型中介绍了与模型无关的内容。

我没有看到为模型提供过滤器有什么问题,可能需要一个代表你所在地区的字符串。如果你想将会话传递给那个,那么请随意,但是通过将会话内容(甚至是阅读)放入模型中,你本质上将两者联系起来......一个模型来会话状态。

在模型中提供一个将适当过滤的方法,然后通过各种方式从控制器传入一个会话变量,但模型不知道过滤器来自会话变量。它只是一个过滤器。

编辑:澄清一下,我会说会话状态是控制器的一部分,绝对 模型

答案 1 :(得分:2)

一般来说,我的域模型只是状态。我知道这对于Evan理论的一些纯粹主义者来说并不是好兆头,但它适用于创建便携式模型,甚至跨异构系统。换句话说,这适用于SOA(虽然我们可以争论代理模式是否在以后更优秀?)

当您升级到MVC时,您正在处理UI模型,而不一定是域模型,尽管许多样本的方式都融合了这两个概念。您的模型是与视图结合的模型(MVVM模式中的ViewModel)。如果您具有此逻辑分隔,则视图模型可以是原始“模型”(域模型?)和您需要显示的任何其他信息的组合。这样可以清楚地分离问题,这很不错。

答案 2 :(得分:1)

如果在Search类中需要Region Filter,则使用Dependency Injection将其传递给它。您的区域过滤器实际上应该是域模型类。区域过滤器应该不知道您在请求之间存储数据的位置。只需确保区域过滤器在需要时使用它。

作为域模型类,属于Controller,但属于Model。请注意,Model不仅仅是数据库,还包括除UI之外的所有内容。控制器是UI层的一部分。它的唯一目的是将当前请求委托给适当的模型。

换句话说,你应该做这样的事情:

public function searchAction()
{
    $customerSearch = new CustomerSearch;
    $customerSearch->setFilter(new RegionFilter($_SESSION));
    $results = $customerSearch->fetchResults();

    // do something with $results on User Interface
}

请注意,我不同意本页其他地方给出的答案,即会话数据或状态属于控制器。它没有。会话数据只是持久化数据。与任何其他持久化数据一样,它属于持久层(也是模型的一部分)。忘记它是会话数据。它是区域过滤数据。

$_SESSION(或任何超全局)周围打一个API以防止耦合到特定环境是有意义的。但是RegionFilterStorage_Session类仍然是模型类。