模型应该有多复杂?
使用 MVC 模式实现模型时,我的模型应该有多复杂?
假设我有几个像这样的表:
- 用户(id,密码,创建...)
- 电子邮件(user_id,电子邮件...)
- 地址(user_id,地址...)
我有一个名为 UserController 的控制器。这个控制器应该允许我登录用户、创建用户等。
<!-- language: php -->
class UserController{
public function create($array){
...
}
public function login($email, $password){
...
}
}
我的模型应该非常原始,仅通过 ORM 实现 CRUD 操作吗?这将导致代码如下:
<!-- language: php -->
class UserController{
public function create($array){
$userModel->username = 'blah';
$userModel->blah = 'blah';
$id = $userModel->save();
$emailModel->id = $id;
$emailModel->email = "emailhere";
$emailModel->save();
//Do the same for addresses
}
public function login($email, $password){
...
}
}
或者,我可以拥有更复杂的模型:
<!-- language: php -->
UserModel{
public function login($email, $password){
//Do the joining and checking here, then return true or false to the controller
}
}
然后在我的控制器中:
<!-- language: php -->
userModel->login($mail, $password);
那么,哪个是更好的方法?将所有逻辑填充到模型中,还是应该让模型只执行基本的 CRUD 操作?最后,如何处理表连接?它们应该在模型中还是在控制器中处理?
干杯
When implementing models using the MVC pattern, how complex should my models be?
Let's say I have got a few tables like so:
- User (id, password, created ...)
- Emails(user_id, email ...)
- Addresses (user_id, address ...)
I have got a controller called UserController. This controller should allow me to log users in, create users, etc.
<!-- language: php -->
class UserController{
public function create($array){
...
}
public function login($email, $password){
...
}
}
Should my models be very primitive, implemeting only CRUD operations via ORM? This would result in code like:
<!-- language: php -->
class UserController{
public function create($array){
$userModel->username = 'blah';
$userModel->blah = 'blah';
$id = $userModel->save();
$emailModel->id = $id;
$emailModel->email = "emailhere";
$emailModel->save();
//Do the same for addresses
}
public function login($email, $password){
...
}
}
Or, alternatively, I could have models that are more complex:
<!-- language: php -->
UserModel{
public function login($email, $password){
//Do the joining and checking here, then return true or false to the controller
}
}
Then in my controller:
<!-- language: php -->
userModel->login($mail, $password);
So, which is the better way? To stuff all the logic into models, or should I have models doing only the basic CRUD operations? Finally, how do I deal with table joins? Should they be dealt within the model, or in the controller?
Cheers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
大多数人会想到“胖模型,瘦控制器”范例,从长远来看它效果更好。
一个很好的经验法则是将模型视为它们自己的实体,例如,如果您将模型移动到不同的框架,它们仍然可以发挥作用。
一个简单的例子是保存有关电子商务网站上的订单的信息。假设您想要保存有关税费的信息,即订单上的税费是多少。执行此操作的抽象方法是...
$tax_amount = $order_amount * (TAX_PERCENTAGE / 100);
我们应该在控制器还是模型中执行此操作?假设我们在控制器中执行此操作,那么......在我们的创建操作和更新操作中,我们将计算税收,这使得维护代码变得更加困难,并且如果电子商务网站的业务规则发生变化(例如,我们开始向免税企业或海外企业销售),那么我们将不得不更改任何保存订单信息的控制器。
然而,如果我们要在订单模型中计算税金,我们将在 save() 方法中执行一次,该方法将在编辑和添加订单时调用。
在我看来,最好在模型中强制执行业务规则,因为它可以使代码更可移植,并且在维护代码时减少麻烦。当然,有人会不同意,这是一个非常主观的领域。
编辑:
将其应用于您提出的具体问题,考虑一下除了您的用户模型之外,您是否在其他任何地方都需要
login()
方法?您可能希望将模型拆分为不同的、更具体的模型。但在这种情况下,您可以从您的用户模型进行扩展。如果你完全拿走你的控制器怎么办?或者,如果您想以完全不同的方式与模型交互(比如将来通过不同的框架)。以这种方式思考,您的用户模型中的登录方法会更好。
就我个人而言,我会在我的模型上创建一个登录方法,因为它是对数据的操作,而这正是我们模型的用途。我还将在我的控制器上创建一个
loginAction()
方法,该方法将在我们的模型上启动login()
方法并执行任何其他操作(例如,记录失败的尝试/重定向)必须在登录后发生,无论成功还是不成功。示例loginAction()
可能如下所示...Most people think of the "Fat Models, skinny controllers" paradigm, and it works better in the long run.
A great rule of thumb is to think about your Models as their own entity, in the sense that if you were to move your models to a different framework for example, they would still be functional.
A simple example would be saving information about an order on an e-commerce website. Let's say you want to save information about Tax, namely how much Tax is on the order. An abstract way of doing this is...
$tax_amount = $order_amount * (TAX_PERCENTAGE / 100);
Should we do this in the controller or the model? Suppose we did it in the controller, well... in our create action and our update action we would be calculating the tax, which makes for harder to maintain code and should the business rules of the e-commerce website change (say, we start selling to Tax exempt businesses or overseas business) then we would have to change any controller that saves order information.
If we were to calculate Tax in our Order model however, we would be doing it once in our save() method, which would be called when editing and adding orders.
Imo, it's better to enforce business rules in your model because it makes for more portable code and far less headaches when it comes to maintaining your code. Of course, there are people who will disagree, and this is a very subjective area.
EDIT:
Applying this to the specific question you asked, think about whether you would ever need the
login()
method anywhere else but your User model? It's possible you might want to split your models into different, more specific ones. But you could extend from your User model in that case.What about if you were to take away your controller completely? Or if you wanted to interface with your models in an entirely different way (say via a different framework in the future). Thinking in this way you would be far better off with your login method in your User model.
Personally, I would be creating a login method on my model because it is an operation on data and that is what our models are for. I would also be creating a
loginAction()
method on my controller which would initiate thelogin()
method on our model and perform any other action (for example, log failed attempts/redirect) that has to happen on post-login, should it be successful or unsuccessful. An exampleloginAction()
may look as follows...所有将要或可以在应用程序的不同部分重用的功能都应该是全局可访问的,以便耦合度较低并且无需重新声明。
我认为您需要一个额外的授权模型和/或当前系统参数。 AuthModel 可以存储有关不同授权角色的信息,SysModel 存储应用程序参数,例如默认登录设置(例如,使用cookie 是或否)。
那么登录方法可以放在 AuthModel 中,在我看来这应该是一个好地方。模型还负责验证输入的数据,因此新用户的创建应该在 UserModel 中。
All functionality which will or could be reused at different parts in the application should be accessbile globally, so that the coupling is low and there is no need to redeclare it.
I think you need an additional model for authorization and/or the current system parameters. The AuthModel could store information about the different authorization roles and the SysModel stores application parameters like the default login settings (e.g. use cookies yes or no).
The login method could be placed in the AuthModel then, which should be a good place in my opinion. Also the models are responsible to validate the inputted data, so the creation of new users should be in the UserModel.