Pull to refresh

Comments 4

— вызывающая сторона логически «не знает» вызываемый класс, но вызываемому классу обязательно нужно, чтобы его вызывали (пример: контроллеру для успешной работы не нужна статистика, но статистике обязательно нужно, чтобы её вызвали из контроллера, потому что иначе она не будет работать)

Я считаю, что это ошибка проектирования, статистика не должна зависеть от того из контроллера она вызвана или нет. Во-первых, как вы её тестируете? Во-вторых, наверняка не за горами планы по вынесению вычисления статистики в отдельное приложение (например, консольное, где нет контроллеров).

— Mapper, наоборот, очень зависит от базы данных, он завязан на неё, и если вместо MySQL ему подсунуть Redis, он сломается

Если это конкретный маппер (в реляционную БД, в json или в другой формат), то этот маппер не может быть реализован по-другому, если это мапер, который работает с другим маппером (например с реализацией более конкретного маппера, даже через общий интерфейс), то это ошибка проектирования.

— классу ArticleController, по большому счёту, наплевать, что ему нужно по пути дёрнуть статистику — это никак не скажется на отображении данных, которое ему поручено его обязанностями
— классу Stat наоборот хочется знать, из каких источников он собирает данные — он должен знать всё о своих источниках, чтобы правильно работать

Вы сравниваете разные сущности. ArticleController — это компонент из высокостоящего «слоя» web-framework, а Stat — компонент доменной модели. Конечно доменная модель занает как работать с объектами доменной модели и что это за объекты. Похоже, что у вас контроллер это «Presenter» из MVC, т.е. он должен получить данные от статистики и передать их во View («вид»). Конечно, контроллеру не важно — пришли эти данные из статистики1 или из статистики2.
— компоненты, требующие входящих вызовов (статистика зависит от того, дернет ли её контроллер)

Все равно сказать, что функция зависит от того, вызовет её кто-нибудь или нет. В чем смысл? Опять же, как вы пишете тесты для своей статистики?

— компоненты, осуществляющие внешние вызовы (ArticleController обязательно должен вызвать кучу классов)

Почему он что-то кому-то должен? Мне кажется, что не должен. Самый минимум необходимый от контроллера — вернуть какой-нибудь результат обработки действия, экземпляр какого-нибудь ActionResult'а, например.

Requests (для случаев, когда вызывающий объект ожидает выполнения действия, но не знает о том, кто будет его совершать)

Сомнительная потребность. Можете объяснить её необходимость, может быть, более детальным примером?

Правильные зависимости это очень важно — попробуйте перенести класс WebDispatcher с высокоуровненными вызовами из одного проекта в другой.

Мне кажется, что переносить надо не один класс, а весь web-framework или какую-то его законченную самодостаточную часть, содержащую этот WebDispatcher.
Я считаю, что это ошибка проектирования, статистика не должна зависеть от того из контроллера она вызвана или нет. Во-первых, как вы её тестируете? Во-вторых, наверняка не за горами планы по вынесению вычисления статистики в отдельное приложение (например, консольное, где нет контроллеров).

вообще-то речь о компоненте сбора статистики, а не о компоненте записи/хранения. Естественно, вторая может быть абстрагирована и не должна зависеть от проекта. Никаких противоречий. С юнит-тестированием тоже всё гладко.
Если это конкретный маппер...

да, это конкретный маппер, всё в порядке
Похоже, что у вас контроллер это «Presenter» из MVC, т.е. он должен получить данные от статистики и передать их во View («вид»)

В примере кода из раздела «практика» видно, я что это не так — речь о записи статистики, а не о показе.
Код всё же советую просмотреть, с ним будет понятнее, о чём речь.
Все равно сказать, что функция зависит от того, вызовет её кто-нибудь или нет. В чем смысл? Опять же, как вы пишете тесты для своей статистики?

Не совсем так. У функции или метода задача выполнить некоторое действие. У модуля задача — реализовать функциональность. Функции, как отдельно взятой сущности, логически всё равно, кто её вызовет, модуль, посвящённой конкретной функциональности (например, «фиксирование статистики просмотра страниц») имеет другую задачу — обеспечить решение задачи, которая на него возложена, и ему важно, чтобы его вызвали из определённого места в процессе работы, т.е. он от этого зависит.
Юнит-тесты пишутся просто — тестируется каждый метод, и так как каждый метод тривиален (просмотрите код), тест на него тоже тривиален (в отличие от методов в стандартных классах-помойках).
Почему он что-то кому-то должен? Мне кажется, что не должен. Самый минимум необходимый от контроллера — вернуть какой-нибудь результат обработки действия, экземпляр какого-нибудь ActionResult'а, например.

Окей, а 1. кому он вернёт результат?, и 2. что потом будет делать тот, кто получит этот результат? 3. кто же вызывает тогда объекты той же статистики, например? 4. от проекта к проекту организация кода может меняться, но я за «тонкие» и чистые контроллеры, определение которых соответствуют MVC. В таком случае, всё так, как я описал.

Сомнительная потребность. Можете объяснить её необходимость, может быть, более детальным примером?

пример в коде есть, даже отдельно заметка на этот счёт есть. цитирую: «обратите внимание на класс PopupMsk27to35, который описывает только поведение, и PopupMsk27to35View, который описывает только логику уровня VIew». Они как раз связаны через Request.

Мне кажется, что переносить надо не один класс, а весь web-framework или какую-то его законченную самодостаточную часть, содержащую этот WebDispatcher

да, это так. вопрос, если WebDispatcher уже успел превратиться в класс-помойку, завязанную на разнообразную логику уровня домена (что случается очень часто при стандартном подходе), это просто так не сделать
Ознакомился с вашей статьей. Разрешите поворчать (так будет интереснее и мне и вам :) )

Возможно я где-то ошибаюсь, но вы придумали новые термины для уже хорошо известных вещей.

* С event-ами все ясно, обычный event-driven подход.
* С request-ами тоже, в некотрых случаях это те же event-ы, или просто прямые вызовы через интерфейс с бизнес-именем.
* Структурирование проекта по фичам, а не по типам компонентов тоже давно известно, например практикуется в FDD.

Соглашусь, довольно оригинально выглядит организация UI — видимо выделять абстрактый view скорее полезно, но опять же компонентных фреймворков пруд пруди.

Резюмируя: мне достаточно близко то, что вы написали. Лично я для себя все это переформулирую в терминах FDD, Event-Driven, Component Web Frameworks и так далее, а вы как хотите :)
Очень приятно, что вам это близко.
Да, Event-driven, Feature-driven, компоненты… про request-ы можно сказать, что это шаблон observer (как и про event-ы).
Оговорка: request-ы — это не event-ы (события — это то, что уже произошло, запрос — то, что необходимо выполить. это, скорее, делегирование)
Пример из жизни:
— для того, чтобы реализовать фичу, нужно чтобы дизайнер что-то отрисовал. Мне как программисту не важно, как это будет сделано, какие инструменты будут использованы, и кто это вообще сделает. Это Requst (то, что следует сделать, но не в моих обязанностях делать это самому)
— на сервере произошла проблема и под нагрузкой упала база данных. Я настроил инструменты для слежения за этим, и как только это произошло, я немедленно реагирую. Это Event. (то, что уже произошло, и я хочу знать об этом, иначе одна из целей моей работы — корректная работа проекта — не будет выполнена)

Совершенно верно, все эти части встречались ранее.
Моя основная мысль такая — если использовать вместе эти принципы, в той комбинации и тем способом, что я описал, мы получим лёгкую автоматизацию процесса разработки и «правильный» с точки зрения бизнес-логики способ реализации фич + возможность генерировать осмысленный код.
Sign up to leave a comment.

Articles