Zend Framework Model Design

I am building an application in Zend Framework. My model is made up of three layers, domain classes, data mapper classes and a service layer which provides an interface for all external communication. Currently the data mapper classes are only used within my service layer and the domain classes are simple php objects only containing information specific to their domain. A very rough example of what I mean....

//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());
    }

}

I would retrieve a user object in the controller like so

$user = $this->_service->fetch($id);

This has worked fine so far but now I want to do this

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

The new data comes from another table and I don't want to pull all this information from the database every time I load a user, I want to lazy load that information when the getRecipeCount function is called. I guess my question is what would be best practice to achieve this? As far as the consumer is concerned the information is specific to the domain of the user so I think that it should be called from the User class. To achieve this the domain class would need to contain its own mapper instance but is that negating the point of having the service class in the first place? I dont really want to be doing this everytime.

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

Any thoughts will be appreciated


Given a User object, there is no doubt tons of stuff that you could ask about this user: get all his groups, get all his posts, get all his recipes, etc.

It's tempting to think that each of these must represent a method of the User object itself:

$groups = $user->getGroups();
$posts = $user->getPosts();
$recipes = $user->getRecipes();
// etc

In this case, an ORM like Doctrine (#FTW!) can help to manage these types of relationships, provide you with a query language with which you can greedy load or lazy load the user entity graph.

But I think that there is space for a different view here. Why do these have to be methods on the User object itself? Could they instead be methods on service/repository classes:

$groups  = $groupService->getGroupsByUser($user);
$posts   = $postService->getPostsbyUser($user);
$recipes = $recipeService->getRecipesByUser($user);
// etc

Each of these service/repository classes would probably be instantiated with its own mapper classes for accessing their underlying data sources. This way there is no issue of lazy/greedy on creating/loading the User object. If you want to get the related entities, then go ahead access them via the appropriate service/repository, precisely when you want them.

Not saying it should always be one way or the other. In fact, saying precisely the opposite: that both approaches have their place. Choosing which one to use in which context involves both some objective analysis of performance and probably no small amount of personal aesthetics.

Just thinking out loud. YMMV.


This seems like a place where having table relationships defined in Model_DbTable_Users() would come i handy. That way you could just perform a findDependentRowset() query on Users at whichever level you felt appropriate. Although it looks like you would likely want to put it at the service level.

Table Relationships

链接地址: http://www.djcxy.com/p/56232.html

上一篇: ACL与域对象和数据映射器?

下一篇: Zend框架模型设计