Давайте предположим, что для приложения Zend Framework установлены следующие таблицы.
user (id)
groups (id)
groups_users (id, user_id, group_id, join_date)
Я применил подход Data Mapper к моделям, который в основном дает мне:
- Model_User , Model_UsersMapper , Model_DbTable_Users
- Model_Group , Model_GroupsMapper , Model_DbTable_Groups
- Model_GroupUser , Model_GroupsUsersMapper , Model_DbTable_GroupsUsers (для хранения отношений, которые можно рассматривать как объекты; обратите внимание на свойство join_date)
Я определяю _referenceMap в Model_DbTable_GroupsUsers:
protected $_referenceMap = array (
'User' => array (
'columns' => array('user_id'),
'refTableClass' => 'Model_DbTable_Users',
'refColumns' => array('id')
),
'App' => array (
'columns' => array('group_id'),
'refTableClass' => 'Model_DbTable_Groups',
'refColumns' => array('id')
)
);
Я имею в виду следующие проблемы с дизайном:
1) Model_Group только отражает поля в таблице групп. Как я могу вернуть коллекцию групп, членом которой является пользователь, а также дату, когда пользователь присоединился к этой группе для каждой группы? Если бы я просто добавил свойство к объекту домена, то мне пришлось бы сообщить об этом групповому мапперу, не так ли?
2) Допустим, мне нужно выбрать группы, к которым принадлежит пользователь. Где я должен положить эту логику? Model_UsersMapper или Model_GroupsUsersMapper ?
Я также хочу использовать механизм карт ссылок (зависимых таблиц) и, вероятно, использовать findManyToManyRowset или findDependentRowset, что-то вроде:
$result = $this->getDbTable()->find($userId);
$row = $result->current();
$groups = $row->findManyToManyRowset(
'Model_DbTable_Groups',
'Model_DbTable_GroupsUsers'
);
Это приведет к двум запросам, когда я мог бы просто написать это в одном запросе. Я помещу это в класс Model_GroupsUsersMapper.
Усовершенствованием было бы добавление метода getGroups к объекту домена Model_User, который лениво загружает группы при необходимости, вызывая соответствующий метод в преобразователе данных, который напрашивается для второго вопроса. Должен ли я позволить объекту домена знать о преобразователе данных?