Laravel традиционно является MVC-фреймворком, но ((ВП:MVC)) не слишком хорошо масштабируется для крупных проектов. Обычно, в конечном итоге получается, что логика содержится во всех секциях: моделях, представлениях и контроллерах, и по мере развития приложения его становится почти невозможно тестировать. В книге Тейлора Отвелла упоминается ((41 шаблон репозитория)), но даже он не способен решить эту проблему масштабируемости. После того, как ((http://travisbennett.net/, коллега)) показал мне ((http://victorsavkin.com/post/42542190528/hexagonal-architecture-for-rails-developers, статью в блоге)) о шестиугольном шаблоне проектирования в Rails, я решил попробовать применить его в Laravel - результаты были потрясающие. %%(Image /packages/proger/habravel/uploads/13-hexagonal-pattern.png, align=right) Эта диаграмма взята из ((http://victorsavkin.com/post/42542190528/hexagonal-architecture-for-rails-developers блога)) и показывает разделение логики доставки и применения. %% Основная идея заключается в том, что маршруты и контроллеры предназначены только для доставки. В контроллере нет никакой логики, и точка. Контроллер похож на вашего почтальона. Он получает адрес (маршрут) и доставляет коробку (модель + представление) по вашему адресу. Ему не нужно беспокоиться о содержимом коробки. Но получается, что почтальон всё равно принимает решения. Например, если сейчас идет дождь, коробка может оказаться либо в вашем автомобиле, иначе, вероятно, на вашем крыльце. Итак, где вы поместите вашу логику? Я называю её сценарием (scenario), но она еще называется примером использования (use cases). Так давайте применим нашу концепцию сценария к нашему придуманному примеру о почтальоне. Вместо того, чтобы почтальон пытался выяснить, что делать с коробкой, он просто будет следовать строгому набору руководящих принципов заранее определенного сценария. Он не делает никаких предположений и делает именно то, что ему сказано. Таким образом, в сценарии, в котором идет дождь, согласно правилам, он должен оставить записку, объяснив ситуацию, и не оставлять коробку под дождём. Это означает, что почтальон не несет ответственности за любые решения. Он просто механизм доставки заказов в соответствии с данными ему инструкциями. == Реализация == Ниже приведены два класса: %%UsersController%% и %%UserScenario%%. Это примеры, показывающие, каким образом можно создать в Laravel пользователя с помощью нашего шестиугольного шаблона со сценариями. %% scenario = $scenario; $scenario->controller = $this; } public function create() { // здесь не нужна логика, мы всегда показываем emptyUser представлению user.create $user = $this->scenario->emptyUser(); $this->layout->nest('content', 'user.create', compact('user')); } public function store() { // возвращаем createUserSuccess или createUserInvalid в зависимости от результата сценария return $this->scenario->createUser(Input::get()); } protected function createUserInvalid($validator, $input) { return Redirect::action('UserController@create')->withErrors($validator)->withInput($input); } protected function createUserSuccess($user) { Auth::loginUsingId($user->id); return Redirect::action('HomeController@dashboard'); } } %% %% user = $user; } /** * просто вернем нового пользователя при создании сценария */ public function emptyUser() { return $this->user; } /** * сценарий, в котором происходит создание нового пользователя... * мы проверяем поля ввода и создаем нового пользователя */ public function createUser($input) { $validation = $this->validator($input, $this->user->creationRules); if ($validation->fails()) { return $this->invoke('createUserInvalid', [$validation, $input]); } $this->user->create($input); return $this->invoke('createUserSuccess', [$user]); } } %% Вы удивлены тем, что здесь делает функция %%invoke()%%? Она реализована в моем классе ((https://gist.github.com/kdocki/3273e52a64cb3da32413#file-basescenario-php, BaseScenario)) и позволяет мне вызывать защищенные функции контроллера. Рефлексия позволяет мне видеть действия, которые не должны иметь маршрутов, привязанных к ним, то есть %%createUserInvalid%% не имеет маршрута и является защищенной функцией. Так что вот, у нас есть контроллер фактически без логики, использующий сценарий. В ((http://www.keltdockins.com/2/post/2014/01/macros-in-laravel-php-hexagonal-pattern-design.html, моей следующей статье)), я буду рассказывать о том, как держать шаблоны Laravel простыми и понятными с помощью макросов.