【问题标题】:Zend Framework application design - should session variables be accessed in the Model layerZend Framework 应用程序设计——应该在模型层访问会话变量
【发布时间】:2011-09-02 19:10:52
【问题描述】:

我正在开发这个访问模型层中的会话变量的应用程序。这似乎是错误的,但愿意被证明是错误的。也许没有错,但在应用程序的大多数地方,会话变量在控制器中处理并作为参数传入,但在其他地方,会话值只是被访问。我错了,这似乎是不好的做法?

编辑: 我不喜欢模型中的会话的一个原因是它似乎使测试变得更加复杂。将其保留为只是传递给函数的参数,然后传递回记录集。

谢谢

【问题讨论】:

  • 想一想您想在命令行脚本中使用您的模型:没有会话。或者在单元测试中。如果您需要一些可能来自会话的数据,最好将其隐藏在一个可以模拟的对象中,以防测试或命令行使用。
  • 不要做这种事!数据层是一回事,业务逻辑是另一回事。使用 Zend_Registry insted 甚至数据映射器。

标签: php zend-framework design-patterns


【解决方案1】:

视情况而定。

我的想法是这样的:

  1. 模型代表您的数据层。
  2. 大多数情况下,数据层将基于 DB 表
  3. Session 只是另一种数据存储介质。
  4. 结论:如果您的模型所代表的数据存储在 Session 中,则可以从模型中访问该数据

一个例子是基于会话的购物车。我的购物车对象是我的会话数据的模型。

【讨论】:

  • 很公平。但我仍然会为会话对象添加一个 getter/setter,以便稍后进行模拟。
  • 我在这个应用程序中看到的问题(以及最初的动机)是#3 不是#2,或者更一致的是,它没有持久化到 db 并且只保留到 php 的会话机制。实际上,您正在获得悬空引用。在这种情况下,要么运行一种不会调用这些特定方法的方式似乎更有意义,除非存在 sess->user_id 变量(即完成 ar 控制器级别),或者通过模型构造函数/初始化管理用户是否有一个 sess->user_id。在测试和 cli 的问题(两者都使用)方面,我可以手动创建 sess 值。
  • @timpone 也许我不明白你所说的悬空引用是什么意思。仅当在另一个持久模型中将会话 ID 存储为外部引用时,才会发生悬空引用问题——这更多是存储/数据库设计问题。我不会将我的持久存储(数据库)和临时存储(会话)关联起来,即使它们都是数据层。我的回答是为了说明,在某些情况下,如果临时存储用于对数据进行建模,那么在模型中引用 Session 是可以接受的。
  • 我认为你不应该从模型访问会话对象。此外,模型不仅仅是“数据层”。这是您的业务逻辑,需要与您的数据源(包括会话变量)分开。
  • @Keyne - 我从未说过模型只是数据层,这个问题的目的和我的回答非常具体,并不打算作为 MVC 架构的概述。也就是说,我表示在特定情况下访问会话是可以接受的。您的评论没有反驳的情况。此外,您对“业务逻辑”的理解有些欠缺——它包括计算和数据存储。此外,如果您想对某个问题进行权衡,请提交答案!
【解决方案2】:

在使用在其中使用该会话的模型之前,控制器 shd 会检查天气会话是否存在。

【讨论】:

  • 我见过这个,但它遇到了模型有其他模型的问题。如果在另一个模型中使用的模型使用会话变量怎么办?似乎在控制器中编写了很多代码来管理实际上应该在控制器中的内容。大声思考比不同意你的观点更多。
  • @timpone 将 session 作为参数传递给模型时,您仍然需要在 controller 中进行所有检查。顾名思义,控制器的工作是提供对模型内部逻辑的控制。
  • +1 同意,您不需要在模型中检查会话,这是插件工作。可能你在你的架构中遗漏了一些东西。否则,这是一个 Zend_Registry 作业。
【解决方案3】:

不,不应该。存储类型应该与您的业务逻辑分开。例如:

我有一个简单的插件来执行访问检查并将用户对象放在注册表中。因此,模型可以访问定义明确的注册表,而不是访问会话。

$User = Zend_Registry::get('User'); // User model object

从理论上讲,一切都应该通过数据映射器访问。将来,如果您从会话存储更改为其他内容,则只需在一个地方进行更新。您的模型不需要知道数据的来源。

如果您采用多条路径来获取数据,那么当您的应用程序变大时,这可能会导致一些问题。

OOP 和分层系统方法的建议是创建专门的对象和层,并保持简单,防止特定操作在整个代码中传播。

但同样,除非您看到优势,否则您无需更改它。 请记住,有时重构比尝试预测所有内容更有效。

【讨论】:

    【解决方案4】:

    会话变量中存储了什么?如果它只是“登录? Y/N',那么它们可能不需要成为模型层的一部分。但是,如果它比这更复杂,那么它们可能与您的业务模式密不可分,应该这样对待。

    Zend Test 文档底部的示例展示了如何使用登录功能测试完整的 MVC。想必您在测试模型时也可以这样做?

    【讨论】:

    • 感谢您指出这一点;就像我认为这取决于一切。在一个复杂的应用程序中,这似乎是灾难的秘诀。一般来说,我发现我总是想对数据进行一些 cli 处理以清理它并且拥有真正的会话变量会使它复杂化。可以做到吗?是 应该做吗?不确定
    猜你喜欢
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 2010-12-01
    • 2012-04-23
    相关资源
    最近更新 更多