传统上,在 MVC 框架(例如 CodeIgniter 或 Kohana)中,我在创建不同页面时创建控制器。将有一个登录控制器,一个家庭控制器等。但最近我了解了更多关于面向目标编程的知识,并想开始使用它。尽管框架使用类,但它与对象的原理不同。
是的。登录控制器是一个对象。但是,例如,我应该在哪里编写我的“用户”类?我是否将它们写在库中并在需要时导入它们?这样做的正确方法是什么,如果有的话。
我只是对如何正确地做到这一点感到困惑。
传统上,在 MVC 框架(例如 CodeIgniter 或 Kohana)中,我在创建不同页面时创建控制器。将有一个登录控制器,一个家庭控制器等。但最近我了解了更多关于面向目标编程的知识,并想开始使用它。尽管框架使用类,但它与对象的原理不同。
是的。登录控制器是一个对象。但是,例如,我应该在哪里编写我的“用户”类?我是否将它们写在库中并在需要时导入它们?这样做的正确方法是什么,如果有的话。
我只是对如何正确地做到这一点感到困惑。
<rant>
如果您从直接克隆 Rails 或受 Rails 架构严重影响的框架开始,那么您并没有真正实现 MVC。Ruby on Rails 框架原本打算成为一个纯粹的快速原型设计框架,这意味着他们在“脚手架的祭坛”上牺牲了大部分 MVC 概念。
基于 Rails 的 PHP 框架用模板替换功能齐全的视图,用一些活动记录实例的集合替换模型层,并让“控制器”处理所有表示和应用程序逻辑。
</rant>
MVC 设计模式的基础是业务逻辑(包含在模型层中)和用户界面(由表示层管理)之间的分离。这两层中的每一个都包含不同的结构组。
User
不是模型。现代 MVC 中没有“模型”。相反,您的User
实例是一个域对象。此外,它不应直接暴露给控制器或其他表示层结构。
表示层和模型层之间的交互应该由服务来执行。模型层中的服务是结构,负责处理域对象和存储抽象(直接数据映射器或通过存储库和/或工作单元)之间的交互。
namespace Controller;
class Authentication
{
// .... snip
public function postLogin( $request )
{
$service = $this->serviceFactory->create('Recognition');
$service->authenticate( $request->getParameter('username'),
$request->getParameter('password') );
}
// .... snip
}
在这种情况下,User
实例位于识别服务内部的某个位置,用于处理用户身份验证的不同业务逻辑方面。并且不要将其与授权混淆。对于 MVC 上下文中的授权,有一些不同的推荐方法。
PS:如果您刚刚开始真正深入研究 OOP,您可能会发现此列表对您的研究很有用。
my two cents
最好将您的 User 类编写为库,因为它不是控制器(假设),并且您不应该通过 URL 直接访问 User 类。因此,如果您希望它是面向对象的,最好的做法是编写一个类。或者,如果您想拥有静态函数,您可以创建一个帮助文件。
我觉得太个性了。真的取决于构建什么样的应用程序。让我们考虑一下 CodeIgniter 或 Kohana,但要针对您的个人框架和个人应用程序。
如果您有简单的登录系统,其中用户只是一个名称和一个 ID,并且所有交互都在应用程序的其他阶段之间,而不是用户之间的交互,那么您的用户类只包含有关用户的信息(简单查询从users
表中检索某些信息的数据库),可以是一个助手。
但在某些应用程序(本例中为平台)中,用户可能与其中的任何其他对象相等。
例如构建一个类似论坛的应用程序,您可能希望拥有警告级别、声誉、各种用户操作日志等。
此外,用户是一个平等的对象,如“主题”,也有喜欢/不喜欢、优先级等。
在这种情况下,您为用户构建模型和控制器。例如,在您的模型中,您将拥有类似的方法
createUser(), getUser(), getUserWarnActions(), updateUserActions(), logUserActionChange()
等等等等。
所有这些方法都将在一个名为 ie 的类中,该类UserModel
扩展了 Model 主类
例如,UserActions 是警告级别、电子邮件更改、用户名更改、声誉更改。
在您的控制器中,您可能希望拥有
updateWarnLevel()
=> 与 交互updateUserActions()
,告诉模型它的动作 = 警告级别,并通过给定值更新它
所以这些方法将在一个类中,即UserController
扩展控制器主类
但是这实际上取决于您如何看待您的 User 类。根据我的说法,将控制器/模型称为警告级别将是不好的做法,因为它是另一个抽象的一部分,而不是单独的抽象。
假设哪个是孩子或父母,我会尝试制作一个结构,如 db 结构,然后创建模型/控制器/助手。
如果您有以下数据库表:
它肯定意味着Users
并且Topics
将是您的应用程序中的模型/控制器,而warn_levels
不会是,因为它们是单独的表,只是因为它们具有一些逻辑,但它们不是父表,只有子表