Я не уверен, что вы подразумеваете под VO. Это объект ценности?
Я большой поклонник подхода DDD (доменного дизайна) (хотя я не считаю себя гуру в этом). В DDD у вас есть так называемые Услуги . Сервис Это действие, которое работает в вашем домене и возвращает данные. Сервис инкапсулирует манипуляции с данными вашего домена.
Вместо того, чтобы контроллер мог выполнять всю логику домена, например, какие элементы извлекать, какие DAO использовать и т. Д. (Почему контроллер должен заботиться о Домене в любом случае?), Он должен быть инкапсулирован в самом Домене, в DDD дело внутри службы.
Так, например, вы хотите получить все элементы категории категории "электроника".
Вы можете написать контроллер, который выглядит следующим образом (извините, если код имеет неверный синтаксис, для примера):
public function showItemsByCategoryAction($categoryName) {
$categoryId = $categoryDAO->findByName($categoryName);
if(is_null($categoryId)) {
//@TODO error
}
$itemIds = $categoryLinkDAO->getItemsByCategoryId($categoryId);
if(empty($itemIds)) {
//@TODO show error to the user
}
$items = $categoryItemDAO->findManyItems($itemIds);
//@TODO parse, assign to view etc
}
Это создает как минимум две проблемы:
- Контроллер FSUC (Жир, тупой уродливый контроллер)
- Код не подлежит повторному использованию. Если вы хотите добавить еще один уровень представления (например, API для разработчиков, мобильная версия веб-сайта и т. Д.), Вам придется скопировать и вставить тот же код (ожидайте, что часть рендеринга представления), и в конечном итоге вы придете к что-то, что будет инкапсулировать этот код, и это то, для чего предназначены Сервисы.
С уровнем Services тот же контроллер может выглядеть как
public function showItemsByCategoryAction($categoryName) {
$service = new Item_CategoryName_Finder_Service();
$items = $service->find($categoryName);
if(empty($items)){
//@TODO show empty page result, redirect or whatever
}
$this->getView()->bind('items', $items);
}
Контроллер теперь чистый, маленький, и вся логика домена заключена в службе, которую можно повторно использовать в любом месте кода.
Теперь некоторые люди считают, что контроллер не должен ничего знать о DAO и взаимодействуют с Доменом только с помощью Сервисов, другие говорят, что можно совершать вызовы DAO из контроллера, нет строгих правил, решать, что лучше подходит для вы.
Надеюсь, это поможет вам!
Удачи:)