我正在加载Zend 1.11和与Doctrine 1.2的集成,并且已经阅读了很多关于服务层使用的内容。
据我所知,服务层位于业务逻辑之上,在控制器和域模型之间添加了一层。
但是,我一直纠结于如何真正实现服务层,主要是因为我有点不确定应该为服务类定义什么类型的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;
}
}
控制器在哪里处理其范围内的域模型,并将它们传递给服务类?
你认为哪种做法更好?
服务类的API是否应该通过只接受或返回本机数据类型(如整数或数组)来隐藏类的组成?
是的,这很理想。如果您强制服务的客户端(在本例中为控制器)传入预先构建的域实体(用户),则会强制客户端了解该域的很多信息。不应该。
您的服务方法也可以是静态的(但它们不一定必须是静态的)。
您并不是真的需要服务类上的App_
前缀。不确定这是ZF社区什么时候开始的,但它已经被货物崇拜致死,真的没有必要。我通常将服务(以及所有特定于应用程序的内容)放在lib
下。更具体地说,我使用src/main/lib
,它与src/test/*
和src/vendor/lib
配合得很好。
至于返回值。。。我通常会让服务方法返回某种集合。数组很好;然而,在许多情况下,更丰富的集合对象是非常有用的(但不是强制性的)。有时我只是使用ZendPaginator对象来强调它的实用性。它不是可用的最丰富的集合对象,但它可以OOTB工作。