Дизайн модели Zend Framework


Я создаю приложение в Zend Framework. Моя модель состоит из трех уровней: классов домена, классов отображения данных и сервисного уровня, который обеспечивает интерфейс для всех внешних коммуникаций. В настоящее время классы сопоставления данных используются только на уровне моего сервиса, а классы домена - это простые объекты 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. Я предполагаю, что мой вопрос заключается в том, что было бы лучшей практикой для достижения этого? Что касается потребителя, то информация специфична для домена пользователя, поэтому я думаю, что ее следует называть из класса пользователя. Для достижения этой цели класс домена должен был бы содержать свой собственный экземпляр mapper, но разве это отрицает необходимость наличия класса обслуживания в первую очередь? Я действительно не хочу делать это каждый раз.

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

Любые мысли будут оценены по достоинству

Author: Andrew Kett, 2012-02-15

2 answers

Учитывая объект пользователя, нет сомнений, что вы могли бы задать массу вопросов об этом пользователе: получить все его группы, получить все его сообщения, получить все его рецепты и т.д.

Заманчиво думать, что каждый из них должен представлять метод самого объекта пользователя:

$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

Каждый из этих классов служб/репозиториев, вероятно, будет создан со своими собственными классами сопоставления для доступа к их базовым источникам данных. Таким образом, нет проблем с ленивостью/жадностью при создании/загрузке объекта пользователя. Если вы хотите получить связанные объекты, то продолжайте получать к ним доступ через соответствующий сервис/хранилище, именно тогда, когда вы этого хотите.

Не говорю, что это всегда должно быть так или иначе. На самом деле, говоря прямо противоположное: что оба подхода имеют свое место. Выбор того, какой из них использовать в каком контексте, предполагает как некоторый объективный анализ производительности, так и, вероятно, немалую долю личной эстетики.

Просто размышляю вслух. ИММВ.

 3
Author: David Weinraub, 2012-02-15 13:06:20

Это похоже на место, где мне пригодились бы отношения таблиц, определенные в Model_DbTable_Users(). Таким образом, вы могли бы просто выполнить запрос findDependentRowset() для пользователей на любом уровне, который вы считаете подходящим. Хотя, похоже, вы, скорее всего, захотите перевести его на уровень обслуживания.

Взаимосвязи таблиц

 0
Author: RockyFord, 2012-02-15 04:59:06