1

我有一个关于我在应用程序中遇到的冲突/难题的问题。

我想为我的所有模型和控制器提供一些通用的“东西”,例如来自缓存的数据或会话信息,以及我的 PDO 包装器的方法。

目前,每个单独的功能控制器和功能模型都扩展了一个基本控制器和基本模型,而后者又扩展了一个执行所有常见操作的对象。

控制器将被路由器/调度程序调用,然后控制器将调用模型以获取一些数据。这样做的问题是它意味着主对象被构造了两次:一次是在调用特征控制器时,另一次是在特征控制器调用特征模型时。

见下图:

我的 MVC 应用程序当前的结构

显然我做错了什么,所以我想知道这个问题是否有某种最佳实践解决方案。

想要的是必须通过控制器将对象加载的内容传递给模型。这意味着任何时候我必须向对象添加一个新的公共元素,我必须将它传递给模型。

$this->cache 或 $this->db 或 $this->session 在控制器和模型(以及未来的助手和杂项类)中始终普遍可用要简单得多。

我将如何解决这个问题?

谢谢 :)

4

2 回答 2

0

我有一种感觉,你的问题的根源是糟糕的架构。

关于 MVC 和受 MVC 启发的设计模式,您必须了解的主要内容是该模式由两层组成:稍后呈现和模型层。这些层不应共享通用功能。控制器(以及视图和模板)是表示层的一部分。

当您在控制器中有或之类$this->cache的变量时,这意味着您有严重的抽象泄漏。这些是存储结构,应该在模型层中隐藏得相当深。如果您的控制器直接与它们交互,则您没有控制器。$this->db$this->session

下一个问题是你的基类(你Object出于某种原因调用的那个......而对象有点是类的实例)。它似乎负责很多,尤其是与存储交互的不同抽象的实例化。如果你的控制器需要一个 PDO 实例(出于某种异常奇怪的原因),那么它应该被注入到构造函数中。缓存和会话管理也是如此。

还有一点就是模型不是对象或类。它是一层。就像表示层一样,它由不同类型的结构组成。通常建议是:

  • 处理逻辑实体的结构,这通常是域对象的用途
  • 一种或多种类型的存储抽象:数据映射器存储库工作单元dao和/或一些类似的结构。
  • 控制上述结构之间交互的东西,使它们不会在表示层中泄漏,通常称为服务

是的,假设使用控制器传递结构是一种不好的做法,你是正确的。它违反了 LoD。相反,您应该为您的控制器提供一个工厂,该工厂实例化您的模型层结构并为它们提供必要的依赖项..这篇文章可能会有所帮助。

我在这个主题上的两分钱..要获得更精确的建议,您必须显示一些代码

于 2012-10-21T00:25:30.287 回答
0

我认为你在解决这个问题上走错了路。如果你正在构建一个 MVC 应用程序,你应该分离关注点,这就是我们使用 MVC 的原因。分离模型、控制器和视图。

你应该定义你需要 Model 做什么,Controller 做什么,并且只将 View 用于表示逻辑。

在正确的 MVC 中,模型是处理业务逻辑、数据库访问、验证等的层。因此模型不是一个类。您可以在一个控制器中使用多种型号。而控制器只是......模型和视图之间的连接。模型应该很胖,控制器应该很轻。

在我看来,你这样做的方式是错误的,因为你可以在模型和控制器中做同样的事情,这不是 MVC 的用途。控制器不应该做任何逻辑,这就是我们使用模型的原因,控制器只告诉模型做什么,并根据他们的反应告诉其他模型做其他事情,或者用成功或错误消息或来自数据库的帖子等呈现视图。

您可以这样做的方法是,一旦您调用了适当的控制器,就可以使用它来获取您需要的模型。再一次,模型由很多类组成,所以你的模型文件夹可能很胖。在 Controller 中,您应该只有访问模型的方法,以便模型可以执行某些操作,并向 Controller 报告它们所做的事情。并根据该返回值执行更多操作或调用 View 进行渲染。

所以你不应该有一个对象可以同时被模型和控制器扩展。

您的模型文件夹可能如下所示:

Models
    - Entities
    - Forms
    - Validators
    - Services
    ...

然后你在你的控制器中调用它们中的任何一个来执行一些操作,并报告回来。如果您确实需要在控制器和模型中具有相同的功能,那么这并不能回答您的问题,但我认为像您开始那样做是错误的。

希望这对您有所帮助,有趣的问题如果可以的话,我会尝试提供更多帮助。

于 2012-10-20T15:18:56.407 回答