{{TOC}} Применение шаблонов проектирования на практике может вызывать некоторые сложности. Представьте себе ситуацию. Маленький ребенок, интересующийся техникой, играет в игрушечные машинки. Тут подходим мы, и предлагаем ему начать проектирование и строительство автозавода по производству автомобилей (это именно то состояние, в котором я находился, когда меня не очень учтиво ввели в тему шаблонов). Но это не должно быть нашей на них реакцию. Данное руководство о двух шаблонах поможет вам существенно улучшить структуру вашего приложения и шаг за шагом постигать и внедрять новые технологии. == Шаблон репозитория == Хранилище является посредником между источником данных и слоем бизнес-логики приложения. Оно создает запросы к источнику данных для получения данных, передает данные из источника данных в слой бизнес-логики и сохраняет изменения из бизнес-сущностей в источнике данных. Хранилище отделяет бизнес-логику от взаимодействий с базовым источником данных или веб-службой. Итак, основной смысл, описанный главным инженером, немного непонятен, поэтому большое спасибо 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 (Тейлору это понравится). На следующей неделе мы рассмотрим тестирование шлюзов и добавление в них проверок и исключений.