Страница 1 из 1

Paul M Jones про action injection

Добавлено: 2017.05.16, 17:57
samdark
Интересные мысли. Когда мы не смёржили action injection в Yii, мысли были примерно такие же...

http://paul-m-jones.com/archives/6589

Re: Paul M Jones про action injection

Добавлено: 2017.05.16, 21:40
zelenin
psr7 подталкивает к использованию экшнов без контроллеров в виде psr7-совместимых мидлварей.
У ADR, предлагаемой Полом, такой же подход. Такой же подход и у всех микрофреймворков.

Re: Paul M Jones про action injection

Добавлено: 2017.05.16, 22:16
ElisDN
Вот так берёшь SiteController из yii2-app-advanced и пытаешся туда Constructor Injection внедрить... И получаешь не то что "запашок", а лютый ад true-Yii-way, который is doing too much:

Код: Выделить всё

class SiteController extends Controller
{
    public function __construct(
        AuthService $authService,
        SignupService $signupService,
        PasswordResetService $passwordResetService,
        ContactService $contactService,
        ...
    )

    public function actionIndex()
    public function actionLogin()
    public function actionLogout()
    public function actionContact()
    public function actionAbout()
    public function actionSignup()
    public function actionRequestPasswordReset()
    public function actionResetPassword($token)
}
где жутко просится Action Injection или костыль помощнее, чтоб тот циганский сброд в конструктре унять...

А потом думаешь, что ж это за индусский код? И тихо делаешь по SRP:

Код: Выделить всё

class SiteController extends Controller
{
    public function actionIndex()
    public function actionAbout()
}

Код: Выделить всё

class ContactController extends Controller
{
    public function __construct(ContactService $contactService)
    public function actionIndex()
}

Код: Выделить всё

class AuthController extends Controller
{
    public function __construct(AuthService $authService)
    public function actionLogin()
    public function actionLogout()
}

Код: Выделить всё

class SignupController extends Controller
{
    public function __construct(SignupService $signupService)
    public function actionIndex()
}

Код: Выделить всё

class ResetController extends Controller
{
    public function __construct(PasswordResetService $passwordResetService)
    public function actionRequest()
    public function actionReset($token)
}
и всё становится вдруг просто и логично. И с чистой кармой идёшь смаковать холивары that SOLID is wrong and Indian RAD is better...

Re: Paul M Jones про action injection

Добавлено: 2017.05.16, 23:56
slavcodev
Прочитал пару абзацев, но учитывая что я понимаю почему в Yii этого нет, то могу уже дать оценку. Бред.
But the fact that your controller has so many dependencies, used only in some cases and not in others, should be an indicator that the class is doing too much. Indeed, it’s doing so much that you cannot call its action methods directly; you have to use the dependency injection container not only to build the controller object but also to invoke its action methods.
Yii-шный action и есть на самом деле Controller, тот что из MVC, потому что именно он как код управляющий данными и представлением за один жизненный цикл приложения (запрос//ответ). Поэтому, ничего страшного и более попахивающего чем то что уже есть в Yii, в этом нет.

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 00:04
zelenin
slavcodev писал(а): 2017.05.16, 23:56 Прочитал пару абзацев, но учитывая что я понимаю почему в Yii этого нет, то могу уже дать оценку. Бред.
But the fact that your controller has so many dependencies, used only in some cases and not in others, should be an indicator that the class is doing too much. Indeed, it’s doing so much that you cannot call its action methods directly; you have to use the dependency injection container not only to build the controller object but also to invoke its action methods.
Yii-шный action и есть на самом деле Controller, тот что из MVC, потому что именно он как код управляющий данными и представлением за один жизненный цикл приложения (запрос//ответ). Поэтому, ничего страшного и более попахивающего чем то что уже есть в Yii, в этом нет.
но он не пишет про контроллер, который MVC, а про контроллер, который объединяет несколько экшнов, для каждого из которых нужны свои зависимости. И в итоге для вызова одного экшна мы инстанциируем контроллер с зависимостями всех экшнов контроллера.

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 00:51
slavcodev
А что такое "контроллер, который объединяет несколько экшенов"? или что такое "экшн"?

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 02:01
samdark
psr7 подталкивает к использованию экшнов без контроллеров в виде psr7-совместимых мидлварей.
PSR-7 чтобы как раз middleware писать, а не экшны. Экшны очень неудобно. Поэтому практически во всех фреймворках, поддерживающих PSR-7, помимо чисто PSR-7 интерфейса есть ещё и интерфейс с сигнатурой и возвращаемым значением попроще.
А что такое "контроллер, который объединяет несколько экшенов"? или что такое "экшн"?
То же, что и в Yii. Controller — это нечто с кучей action. Action — отдельный класс с методом run().

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 02:28
slavcodev
samdark писал(а): 2017.05.17, 02:01 То же, что и в Yii. Controller — это нечто с кучей action. Action — отдельный класс с методом run().
Интересное определение. Кто это придумал? Можно ссылку на литературу?

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 02:41
samdark
Или Microsoft в ASP.NET или DHH в рельсах. Кто первый был не знаю:

- http://guides.rubyonrails.org/action_co ... nd-actions
- https://msdn.microsoft.com/en-us/librar ... .100).aspx

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 08:31
SiZE
slavcodev писал(а): 2017.05.17, 02:28 Интересное определение. Кто это придумал? Можно ссылку на литературу?
Это еще в первом зенде даже

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 11:18
samdark
Первый зенд был позже рельс и ASP.NET.

Re: Paul M Jones про action injection

Добавлено: 2017.05.17, 17:00
slavcodev
samdark писал(а): 2017.05.17, 02:41 Или Microsoft в ASP.NET или DHH в рельсах. Кто первый был не знаю:

- http://guides.rubyonrails.org/action_co ... nd-actions
- https://msdn.microsoft.com/en-us/librar ... .100).aspx
Т.е. это не каки-либо правила или паттерны, это имплементация в определенных фреймворках.
Это никак не опровергает того что я написал.
По MVC, контроллер это не класс Controller и его наследники, это ответственность поставленная на какой-то код, управлять V + M.
Код, будь то отдельный объект (названный Action в Yii) или метод объекта,
который группирует для "удобства" несколько методов с подобной ответственностью.
В любом случае, каждый контроллер имеет свои зависимости и их как-то надо инжектить.
Если для контроллера отдельным классом (extends Action) решается стандартно,
то для контроллеров сгруппированных в один God-object с громким названием Controller,
это уже проблемы тех авторов фреймворков кто придумал такую группировку для "быстрой разработки" и "простого кода".
Это может быть setter injection, или просачивания Service Locator-а.
Ну или инъкекция в эти методы "экшены" могло быть элегантным решением.

Я не стал бы называть это "code smell", уж точно оно не попахивает больше чем группировка "экшенов" в один объект.
SiZE писал(а): 2017.05.17, 08:31 Это еще в первом зенде даже
Не знаю как в первом зенде но во втором, на сколько я помню там запрос роутится на Controller::dispatch(). Т.е. один запрос - один объект (контроллер). Правда и там был один из вариантов юзать "облегченную форму", где имплементация одного из Controller::dispatch() как раз роутить дополнительно на метод. Но это было не обязательно и даже не рекомендовано.

Re: Paul M Jones про action injection

Добавлено: 2017.05.18, 13:34
samdark
Если так сделали десятки фреймворков, по сути это уже стало паттерном... хорошим или плохим — это уже другой вопрос.

Re: Paul M Jones про action injection

Добавлено: 2017.05.18, 14:22
slavcodev
Ну я и не хотел обсуждать, плохо это или хорошо. Я лишь подчеркнул, что если метод (экшн) разруливает запрос (теоретически являясь контроллером данного запроса), то у него, метода, есть зависимости, и имплементация инъекции их параметрами в метод, является более элегантным решением нежели: инъекция через сеттеры, инъекция все и вся в конструктор класс содержащим этот метод, или доступ к контейнеру в экшене. Других вариантов я не знаю. Поэотму говорить о code-smell, это лукавство, попытка оправдать bad decision, когда "десятки фреймворков сделали так".

Re: Paul M Jones про action injection

Добавлено: 2017.05.18, 14:42
zelenin
slavcodev писал(а): 2017.05.18, 14:22Других вариантов я не знаю.
собственно статья этому и посвящена. Пол "топит" за свой ADR, в котором как и в современных psr-7 фреймворках экшн является отдельным классом без родительского контроллера.