模型应该有多复杂?

时间:2011-07-10 09:39:25

标签: php model-view-controller orm models crud

使用MVC模式实现模型时,我的模型应该有多复杂?

假设我有几张这样的表:

  • 用户(id,密码,已创建...)
  • 电子邮件(user_id,email ...)
  • 地址(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操作?最后,我如何处理表连接?它们应该在模型内还是在控制器中处理?

干杯

2 个答案:

答案 0 :(得分:3)

大多数人都会想到“胖模特,瘦身控制者”的范例,从长远来看它会更好。

一个很好的经验法则是将您的模型视为自己的实体,从某种意义上说,如果您将模型移动到不同的框架,它们仍然可以正常运行。

一个简单的例子是在电子商务网站上保存有关订单的信息。假设您要保存有关税的信息,即订单中的税金额。这样做的一种抽象方式是......

$tax_amount = $order_amount * (TAX_PERCENTAGE / 100);

我们应该在控制器或模型中执行此操作吗?假设我们是在控制器中完成的,那么......在我们的创建操作和更新操作中,我们将计算税收,这会使代码更难维护,并且电子商务网站的业务规则会发生变化(例如,我们开始向免税企业或海外业务销售)然后我们将不得不更改任何保存订单信息的控制器。

如果我们要在Order模型中计算Tax,我们会在save()方法中执行一次,在编辑和添加订单时会调用它。

public function save() {
    //calculate tax first
    $q = $this->db->query($sql);
}
Imo,最好在模型中实施业务规则,因为它可以提供更多可移植代码,而且在维护代码方面要少得多。当然,有些人会不同意,这是一个非常主观的领域。

编辑:

将此问题应用于您提出的具体问题,请考虑除了您的用户模型之外,您是否还需要login()方法?您可能希望将模型拆分为不同的,更具体的模型。但在这种情况下,您可以从用户模型扩展。

如果要完全取走控制器怎么样?或者,如果您想以完全不同的方式与模型交互(比如将来通过不同的框架)。通过这种方式思考,您的用户模型中的登录方法会更好。

就个人而言,我会在我的模型上创建一个登录方法,因为它是对数据的操作,这就是我们的模型。我还将在我的控制器上创建一个loginAction()方法,该方法将在我们的模型上启动login()方法执行任何其他操作(例如,log failed attempts / redirect)必须在登录后发生,如果它成功或不成功。示例loginAction()可能如下所示......

class UserController extends GenericController {
    public function loginAction() {
        $post = $this->form->getPost();
        if(UserModel::login($post)) {
            //do something
        } else {
            //do something else
        }
    }
}

答案 1 :(得分:0)

应用程序中不同部分将要或可以重用的所有功能都应该是全局访问,因此耦合很少,无需重新声明它。

我认为您需要一个额外的授权模型和/或当前的系统参数。 AuthModel可以存储有关不同授权角色的信息,SysModel可以存储应用程序参数,例如默认登录设置(例如,使用cookie是或否)。

登录方法可以放在AuthModel中,在我看来应该是个好地方。此外,模型负责验证输入的数据,因此新用户的创建应该在UserModel中。