MVC与程序状态 - 模型应该是愚蠢的吗?

发布于 2024-10-15 04:40:57 字数 734 浏览 6 评论 0原文

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

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

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

有什么想法吗?谢谢!


编辑:感谢各位的讨论。我知道重叠的问题,但很难找到有关该主题的一般性讨论 - 我搜索“MVC 模型程序状态”时发现了大量有关 ASP.NET-MVC 特定讨论的问题,这些问题在实现中陷入困境细节。

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

I'm using a framework which uses the MVC paradigm. It's CodeIgniter, but my question isn't about the framework specifically - it's more generally about best practices when working with MVC.

I'm using $_SESSION variables to maintain some state variables (user selections, some temporary preferences, some data filtering options). This is easy enough to do, but I found that I was splitting the use of these variables across both models and controllers. Sometimes I would update one in a controller, and look it up in a model. This started to "smell" funny, because it occurred to me that it might not be a good idea to make the models "aware" of all those settings. Shouldn't the models just accept requests for fetching/manipulating data, and only be concerned with what was explicitly in the request (without having to look up external variables)?

Here is an example: I have one session variable called $_SESSION['regionFilter']. This is created and updated in a controller, and represents a sales region the user wants to "drill down" to. When a controller requests some data from a model, I'm currently having the model look up the $_SESSION['regionFilter'] variable, and use it when it's creating its SQL for the database. It seems like it might make more sense to make the model "dumb" regarding program state, and have the controller somehow bundle the $_SESSION['regionFilter'] variable into its request if it wants it.

Any thoughts? Thanks!


Edit: Thanks for the discussion, folks. I'm aware of the overlapping questions, but had a hard time finding a general discussion on the topic - my searches for "MVC model program state" turned up slews of questions about ASP.NET-MVC-specific discussions which were mired in implementation details.

I've marked the question as closed. Thanks again for your thoughts!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江挽川 2024-10-22 04:40:57

我认为你担心它闻起来很奇怪是完全正确的。您刚刚向模型中引入了一些与模型无关的内容。

我不认为向模型提供过滤器有什么问题,也许需要一个代表您所在区域的字符串。如果您想将会话传递给它,那么请随意,但是通过将会话内容(甚至读取)放入模型中,您已经将两者本质上联系起来......一个模型会话状态。

在模型中提供一个将进行适当过滤的方法,然后无论如何从控制器传递会话变量,但模型不知道过滤器来自会话变量。这只是一个过滤器。

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

I think you're quite right in worrying about it smelling funny. You've just introduced something that has nothing to do with the model, in to the model.

I don't see anything wrong with providing a filter to the model, perhaps something that takes a string that represents your region. If you want to pass the session in to that, then feel free, but by putting the session stuff (even reading) in to the Model, you've intrinsically linked the two... A model to a session state.

Provide a method in the Model that will filter appropriately, and then by all means pass in a session variable from the controller, but the model has no idea that the filter came from the session variable. It's just a filter.

EDIT: To clarify, I'd say that session state is part of the controller, definitely not the model.

丘比特射中我 2024-10-22 04:40:57

一般来说,我的领域模型只是状态。我知道这对于埃文理论的一些纯粹主义者来说并不是一个好兆头,但它对于创建可移植的模型非常有效,甚至可以跨异构系统。换句话说,这对于 SOA 很有效(尽管我们可以在以后争论代理模式是否更优越?)

当您升级到 MVC 时,您正在处理一个 UI 模型,而不一定是一个域模型,尽管这样可以许多示例融合了这两个概念。您的模型是与视图(MVVM 模式中的 ViewModel)结合的模型。如果您有这种逻辑分离,您的视图模型可以是原始“模型”(域模型?)和您需要显示的任何其他信息的组合。这也使得关注点得到了清晰的分离,这很好。

In general, I have domain models that are state only. I know this does not bode well with some purists of Evan's theories, but it works well for creating models that are portable, even across heterogenous systems. This works well for SOA, in other words (although we can argue whether the surrogate pattern is superior at a later date?)

When you move up to MVC, you are dealing with a UI model and not necessarily a domain model, alhthough way to many samples blend the two concepts. Your model is a model that is married to a view (a ViewModel in the MVVM pattern). If you have this logical separation, your view model can be a combination of the original "model" (domain model?) and any other information you need to display. This makes a clean separation of concerns also, which is nice.

自由如风 2024-10-22 04:40:57

如果您的搜索类中需要区域过滤器,则使用依赖注入将其传递到其中。您的区域过滤器实际上应该是一个域模型类。该区域过滤器应该不知道您在请求之间存储数据的位置。只需确保区域过滤器在需要时拥有它即可。

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

换句话说,您应该这样做:

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

    // do something with $results on User Interface
}

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

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

If your Region Filter is required inside your Search class, then use Dependency Injection to pass it into it. Your Region Filter should actually be a Domain Model class. That Region Filter should be unaware of where you store it's data between Requests. Just make sure the Region Filter has it, when it needs it.

As a Domain Model class it does not belong to the Controller, but the Model. Note that the Model is not just the database, but everything except the UI. The controller is part of the UI layer. It's only purpose is to delegate the current Request to the appropriate models.

In other words, you should be doing something like this:

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

    // do something with $results on User Interface
}

Note that I do not agree to the answer given elsewhere on this page that session data or state belongs to the controller. It doesn't. Session data is just persisted data. Like any other persisted data, it belongs to the persistence layer (which is also part of the Model). Forget that it is Session data. It is Region Filter data.

It makes sense to slap an API around the $_SESSION (or any superglobal) to prevent coupling to a specific environment. But a RegionFilterStorage_Session class would still be a model class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文