Применение шаблонов проектирования на практике может вызывать некоторые сложности. Представьте себе ситуацию. Маленький ребенок, интересующийся техникой, играет в игрушечные машинки. Тут подходим мы, и предлагаем ему начать проектирование и строительство автозавода по производству автомобилей (это именно то состояние, в котором я находился, когда меня не очень учтиво ввели в тему шаблонов). Но это не должно быть нашей на них реакцию. Данное руководство о двух шаблонах поможет вам существенно улучшить структуру вашего приложения и шаг за шагом постигать и внедрять новые технологии.
Шаблон репозитория
Хранилище является посредником между источником данных и слоем бизнес-логики приложения. Оно создает запросы к источнику данных для получения данных, передает данные из источника данных в слой бизнес-логики и сохраняет изменения из бизнес-сущностей в источнике данных. Хранилище отделяет бизнес-логику от взаимодействий с базовым источником данных или веб-службой.
Итак, основной смысл, описанный главным инженером, немного непонятен, поэтому большое спасибо MS за это раскрытое определение. Это сбивает с толку, потому что многие люди будут говорить: «Eloquent отделяет мои данные от бизнес-логики, и предоставляет мне прекрасный API и абстракцию».
Но ORM фактически не подпадает под шаблон хранилища. На практике, единственный получаемый вами слой абстракции — это драйвер PDO для работы с базой данных (да, гипотетически вы могли бы реализовать плоский файловый драйвер, который не полагается на PDO, или даже драйвер Mongo, если вам нравится говорить о «больших данных», «Series A Rounds», или что-нибудь ещё такое же туманное).
Отличным шаблоном для Laravel-проектов является добавление слоя абстрактного репозитория перед вашей моделью, позволяющего выполнять такие функции, как создание, поиск, удаление и т.д. Например, подумайте над созданием тегов базовой системы управления взаимоотношениями с клиентами (tag-based crm). Сначала у вас есть набор тегов в списке пользовательской модели. Таким образом, используя традиционные методы Eloquent, ваш код, вероятнее всего, выглядит следующим образом:
$users = User::where('tags', 'like', $tag)->get();
Но переход к связи «многие-ко-многим» означает, что везде, где имелся вышестоящий запрос, вам придется заменить код следующим образом:
$tags = Tags::with('users')->where('tag', $tag)->get();
$users = $tags->users;
Теперь подумайте еще раз, как перенести все в результирующие SQL-запросы или файловое хранилище.
С другой стороны, создание репозитория дает возможность получить абстракцию, поэтому ваш контроллер будет выглядеть следующим образом:
$users = $this->userRepository->getWhereTag($tag);
public function getWhereTag($tag)
{
// Здесь ваш запрос
}
Кроме того, в будущей статье мы рассмотрим огромные преимущества шаблона репозитория с точки зрения разработки через тестирование (TDD) и разработки через интерфейсы (Interface Driven Design).
Шаблон шлюза
Шлюз инкапсулирует семантический разрыв между объектно-ориентированным слоем домена и соотношением, ориентированным на сохранение слоя.
Повторим: определения могут нас запутать. Высказывание выше кажется таким элементарным, что вы, наверное, глядя на вашего руководителя, улыбаетесь, и сравниваете полезность этого знания с пониманием того, почему хэш-таблицы всегда имеют длину как простое число.
Одной из самых сложных частей любого MVC-приложения является создание всех связанных моделей, необходимых для простой формы. Каждый раз, с синтаксисом Eloquent в Laravel, контроллер будет иметь следующий не очень удобный формат.
$input = Input::all();
$comment = new Comment(array('message' => $input['message']));
$post = Post::create(array('title' => $input['title']));
$comment = $post->comments()->save($comment);
Все становится еще хуже, когда вы рассматриваете вопрос о включении проверки и других факторов. Получается действительно не очень семантически красиво и правильно, не так ли? Что, если мы заменим вышеописанное этим:
$post = $this->postGateway->createPostAndCommentWithInput(Input::all());
Теперь ваш контроллер красив и краток, оставаясь семантически верным, и остается только беспокоиться о разборе входных данных.
Единственное, что следует отметить — некоторые архитекторы называют это службами, но я предпочитаю оставаться в стороне от этой терминологии, учитывая, что многие разработчики, использующие службы, реализуют такие вещи, как проверки данных, рассылки сообщений и т.д. Вместо этого, мы ограничиваем шлюзы для того, чтобы сократить семантику, работающую с сохраняющими отношениями. В дополнение скажем, что мы не хотим возвращаться к использованию наших API-контроллеров в шаблоне HMVC (Тейлору это понравится).
На следующей неделе мы рассмотрим тестирование шлюзов и добавление в них проверок и исключений.