Php Zend框架模型设计

Php Zend框架模型设计,php,zend-framework,design-patterns,architecture,model,Php,Zend Framework,Design Patterns,Architecture,Model,我正在Zend框架中构建一个应用程序。我的模型由三层组成,域类、数据映射器类和服务层,服务层为所有外部通信提供接口。目前,数据映射器类仅在我的服务层中使用,域类是简单的php对象,仅包含特定于其域的信息。我的意思的一个非常粗略的例子 //domain class public class User{ // data and functions specific to the user domain } //service class public class UserService{

我正在Zend框架中构建一个应用程序。我的模型由三层组成,域类、数据映射器类和服务层,服务层为所有外部通信提供接口。目前,数据映射器类仅在我的服务层中使用,域类是简单的php对象,仅包含特定于其域的信息。我的意思的一个非常粗略的例子

//domain class
public class User{
   // data and functions specific to the user domain
}

//service class
public class UserService{
    // service contains an instance of the mapper class
    protected $_mapper = 

    public function fetch($id){
        return $this->_mapper->find($id);
    }
} 

//mapper class
public class UserMapper{
    protected $_dbTable = new Zend_Db_Table('user');

    public function find(){
        return new User($this->_dbTable->find($id)->current());
    }

}
我会像这样在控制器中检索用户对象

$user = $this->_service->fetch($id);
到目前为止,这一切都很好,但现在我想这样做

$user = $this->_service->fetch($id);
$recipeCount = $user->getRecipeCount();
新数据来自另一个表,我不希望每次加载用户时都从数据库中提取所有这些信息,我希望在调用getRecipeCount函数时延迟加载这些信息。我想我的问题是,实现这一目标的最佳实践是什么?就消费者而言,信息是特定于用户域的,因此我认为应该从用户类调用它。要实现这一点,域类需要包含自己的映射器实例,但这是否否定了首先拥有服务类的意义?我真的不想每次都这样

$recipeCount = $this->_service->getRecipeCount($user);

任何想法都将受到欢迎

这似乎是一个在
Model\u DbTable\u Users()
中定义表关系的地方。这样,您就可以在您认为合适的级别上对用户执行
findDependentRowset()
查询。尽管看起来您可能希望将其置于服务级别


给定一个用户对象,毫无疑问,你可以问这个用户很多问题:获取他的所有群组、所有帖子、所有食谱等等

很容易想到,其中每一个都必须代表用户对象本身的一个方法:

$groups = $user->getGroups();
$posts = $user->getPosts();
$recipes = $user->getRecipes();
// etc
在这种情况下,类似ORM的原则(#FTW!)可以帮助管理这些类型的关系,为您提供一种查询语言,您可以使用该语言贪婪地加载或延迟加载用户实体图

但我认为,这里有不同观点的空间。为什么这些必须是用户对象本身上的方法?它们是否可以改为服务/存储库类上的方法:

$groups  = $groupService->getGroupsByUser($user);
$posts   = $postService->getPostsbyUser($user);
$recipes = $recipeService->getRecipesByUser($user);
// etc
这些服务/存储库类中的每一个都可能使用自己的映射器类进行实例化,以访问其底层数据源。这样,在创建/加载用户对象时就不会出现懒惰/贪婪的问题。如果您想获取相关实体,那么可以在需要时通过适当的服务/存储库访问它们

不说它应该总是这样或那样。事实上,恰恰相反:这两种方法都有自己的位置。选择在哪种语境下使用哪一种,既涉及对表演的客观分析,也可能涉及不小的个人美学


只是大声思考。YMMV.

谢谢,我实际上在mapper类中使用了Zend_Db_表的一个实例。我的想法是将所有与数据库相关的内容保留在域类之外。我想问题更多的是,当域类想要触发另一个数据库调用时,如何访问mapper类。在我看来,在域类中有另一个映射器实例似乎正在从一个简单的php域类中移开。这正是ORMs最擅长的。我推荐原则2。谢谢。这很有帮助。我有其他服务可以使用这些相关的映射器类。我想我只是想要一种简单的方法来获取这些额外的数据,而不必在控制器中显式地调用它。e、 g我想在控制器中使用服务获取我的用户类,然后让视图能够通过调用$User->getRecipeCount函数访问数据。如果我只是获取配方列表,我会使用$recipeService->getRecipesByUser($User),我认为这里的区别在于,在消费代码看来,数据是用户域的一部分,而不是配方域。我希望这有意义?