服务层:它应该隐藏域模型的API吗?

时间:2012-04-05 16:03:16

标签: php model-view-controller service-layer

我正在加载Zend 1.11并与Doctrine 1.2集成,并且已经阅读了很多关于Service Layers的使用。

据我了解,Service Layers位于业务逻辑之上,在控制器和域模型之间添加了一层。

但是,我一直坚持如何实际实现服务层,主要是因为我不确定应该定义的服务类的API类型。

首先,给定一个服务类App_Service_Memberships,它将处理具有App_Model_Group和用户为App_Model_User的业务实体组:

服务类的API是否应通过接受或返回所述域模型的实例来公开类的组成?

或者服务类的API是否应该通过仅接受或返回整数或数组等本机数据类型来隐藏类的组合?

喜欢说:

class App_Service_Memberships
{

    public function addUserToGroup($user_id, $group_id)
    {

        //Create or retrieve domain models here and operate on them; handle persistence.
        $membership = new App_Model_Membership();

        $membership->member->user_id = $user_id;
        $membership->group->group_id = $group_id;
        $membership->join_date = date("Y-m-d H:i:s");

        $membership->save();

        return $membership->toArray();
    }

    public function getMembersOfGroup($group_id)
    {
         $groupMembers = array();

         //Query objects here with Doctrine or the ORM of choice...

         foreach($results as $membership){
             $groupMembers[] = $membership->member->toArray();
         }

         return $groupMembers;
    }
}

控制器只是将整数作为参数(表单中的数据或其他服务类的输出)传递给服务类,完全忽略了所涉及的域模型。

而不是:

class App_Service_Memberships
{
    public function addUserToGroup(App_Model_UserInterface $user, App_Model_Group $group)
    {
        //Create or retrieve domain models here and operate on them; handle persistence.
        $membership = new App_Model_Membership();

        $membership->member = $user;
        $membership->group = $group;
        $membership->join_date = date("Y-m-d H:i:s");

        $membership->save();

        return $membership;
    }

    public function getMembersOfGroup(App_Model_Group $group)
    {
         $groupMembers = array();

         //Query memberships here

         foreach($results as $membership){
             $groupMembers[] = $membership->member;
         }

         return $groupMembers;
    }
}

控制器确实在其范围内处理域模型,并将它们传递给服务类?

您认为哪种做法更好?

1 个答案:

答案 0 :(得分:1)

  

...服务类的API是否应该通过仅接受或返回整数或数组等本机数据类型来隐藏类的组合?

是的,这是理想的。如果强制服务的客户端(在这种情况下为控制器)传入预构建的域实体(用户),则会强制客户端了解有关域的许多信息。它不应该。

您的服务方法也可以是静态的(但不一定是这样)。

您的服务类 前缀App_。不确定这是什么时候开始在ZF社区,但它已被货物定为死亡,并没有必要。我通常将服务(以及所有应用程序特定的)放在lib下。更具体地说,我使用的src/main/lib适用于src/test/*src/vendor/lib

至于返回值...我通常有服务方法返回某种集合。阵列很好;但是,在许多情况下,更丰富的集合对象非常有用(但不是强制性的)。有时我只是使用Zend Paginator对象来实现它。它不是最丰富的集合对象,但它可以工作OOTB。