【问题标题】:MVC - How to pass data to serviceMVC - 如何将数据传递给服务
【发布时间】:2014-01-25 07:09:31
【问题描述】:

我对如何使用 MVC 执行插入和更新语句有点困惑。 是否可以在控制器中创建对象实例并将其传递给服务以保存它,还是将数据传递给服务并处理其中的所有其他内容?

插入

在我的控制器中类似于:

$userservice->insert("myname","mypassword");

在我的 UserService 中:

function insert($username,$password){
      $user = ORM::for_table('user')->create();
      $user->username= $username;
      $user->password= $password;
      $user->save();
}

更新

在我的控制器中类似于:

$userservice->update("myname","mypassword",1);

在我的 UserService 中:

function insert($username,$password,$id){
      $user = ORM::for_table('user')->find($id);
      $user->username= $username;
      $user->password= $password;
      $user->save();
}

这是好的做法吗? 因为我看到很多这样的答案,例如在控制器中创建用户并将其传递到存储库以保存它: Proper Repository Pattern Design in PHP? 但我不喜欢在控制器中创建用户的想法......

【问题讨论】:

    标签: php model-view-controller


    【解决方案1】:

    控制器属于应用层,只控制活动。在您的示例中,活动是为现有用户或新用户创建和更新。这些操作属于包含服务的领域层。因此,服务将域封装为看门人,并像门面一样提供解析域的操作。

    可以在控制器中创建对象实例并将其传递给服务以保存它,还是将数据传递给服务并处理其中的所有其他内容?

    该服务应提供一种方法来传递ValueObject。 ValueObjects 更好地封装大量数据(用户的属性值)。在服务内部,ValueObject 应该委托给 Filter 和 Validator。如果验证没有失败,ValueObject 将被委托给DataMapper。 DataMapper 会将 ValueObject 的属性映射到 UserRepository (ORM) 的数据模型。存储库通常需要另一种数据模型,例如对象与 MySQL 等基于 RDBMS 的存储介质。

    这种方法应该严格分离层之间的关注点,以提高可维护性和可互换性。服务应该是精简的并充当域对象(过滤器、验证器等)的委托者,例如参见Service Layer Pattern

    那么,值对象应该在哪里创建呢?

    我希望该服务为此提供一种方法:getEntityPrototype() 使用 prototype pattern。 命名时要小心。 ValueObject 是一个没有身份的对象。 Entity 是一个具有身份的对象(这里是用户的 id)。对于现有用户,您将有一个类似getUserById($id) 的方法,它应该返回一个用户实体。如果给定 id 的用户不存在,它应该返回一个NullObject。要创建一个新的用户getEntityPrototype() 将返回一个还没有身份的用户实体,因此您将其称为 ValueObject 或更好的实体原型。在设置属性(例如通过 FormObject)并持久化此对象后,该对象是一个真实实体。在此服务的工厂中,您可以设置 EntityPrototype。

    【讨论】:

    • 好的,谢谢这个很好的解释,但有一个问题:你在哪里创建你的价值对象?我知道您不应该在控制器中创建对象,那么如何将它们从控制器传递到服务?
    • 我添加了一个新部分“那么,应该在哪里创建一个值对象?”回答你的问题
    【解决方案2】:

    在这种情况下,您应该考虑的是,如果类只有一项职责

    Controller 决定动作的流程。如果需要注册一个用户,那么它会注册他,但是它不应该定义如何去做,而是要求一个服务来完成这个任务并得到结果。

    另一方面,您应该拥有某种UserManager 来更新、创建和获取用户——这是单一的责任吗?有点,是的 - 它在广义上管理它们。

    不过,您的方法名称有一个小问题。您应该使用 registerUser 而不是 insert,因为这样更容易判断它的实际作用。

    【讨论】:

    • 用户管理器是什么意思来更新、创建……这就是服务的作用,那么为什么要创建管理器呢?
    • 名字不同。
    • 所以您是在建议我将我的用户服务称为“UserManager”?
    • 几乎是的。名称应该更具描述性 “服务”并不能真正说明它的作用。经理解释得更多,但您可能仍然可以获得更多创意。
    【解决方案3】:

    您应该将数据传递给模型。 MVC 是关于划分任务的控制器 - 处理应用程序流,模型 - 包含所有业务登录数据库等和视图 - 在这里您决定如何显示。基本上UI部分都存放在这里

    因此控制器应该将数据发送到模型,模型决定如何处理数据。以这种方式编码的好处是,将来如果您想更改代码中的某些内容,您知道在哪里查看,或者如果您要求设计师重新设计您的网站,您只需给他VIEW部分代码。如果设计师做了一些导致错误的事情,纠正它不会花费太多时间。如果你正确地遵循 MVC 添加、更新或维护功能不会有问题

    【讨论】:

    • 我不同意将“所有业务逻辑”放入模型中。这与将其放入控制器中一样错误(或一样正确)。单独的 MVC 什么都不是,对于更大的应用程序,您应该考虑额外的层。
    • @ckonig 对我来说,模型也是一个文件夹,由一组有助于实现业务目标的文件组成。但我总是觉得我错过了一些东西,因为我的目标是不仅在同一个应用程序中重用代码,而且在其他应用程序中重用代码,并且我制作了自己的 MVC。如果你能找到一个链接到我,它反映了你对 MVC 的想法;我很想从中学习。我也在制作一个大型应用程序,这将帮助我使应用程序更加强大。谢谢你..!
    • 这两个是 ASP.NET 的特定问题,但它们朝着正确的方向发展:stackoverflow.com/questions/235233/…stackoverflow.com/questions/7777770/… - 就我个人而言,我喜欢使用模型来表示数据源中的数据(持久性模型)以及隐藏视图数据复杂性的 ViewModel。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多