Сообщение Re: Фасад доменной модели - это God-объект? от 21.05.2024 17:26
Изменено 21.05.2024 17:41 Pauel
Re: Фасад доменной модели - это God-объект?
Здравствуйте, zelenprog, Вы писали:
Z>В ней говорится, что обращение из пользовательского интерфейса к бизнес-логике надо обязательно выполнять через Фасад.
Z>Вот картинка:
Фасад или не фасад, дело десятое. UI и БЛ нужно изолировать друг от друга. Обоснование — разная частота и причины изменений, т.е. можно и нужно менять эти вещи независимо друг от друга.
Ваш условный фасад 25 лет назад выглядел вот так
Унутре контроллер найдет команду, которая реализует ну вот например "toggle.show.utilization"
связывание контролера и команд делается по имени, например, так
Привязка команды к кнопке задавалась вот так
А вот собственно команда
Бенефиты — ui знает только как вызвать контроллер. Контроллер знает только обобщенный интерфейс команд. Команда знает протокол работы с бл, но ничего про саму бл.
Сейчас, спустя 25 лет, это переизобретено под называнием Redux, см жээс фронтенд.
Ключевые отличиян
Было
controller вызывает команду а потом обновляет view — или шлет сигнал, или вызывает у каждой метод update
Стало
view обновляется через store.subscribe(state => view.render(state))
+ вместо команд у вас редюсеры-мидлвары, приседания с иммутабельностью и конские издержки по перформансу и памяти как следствие. зато крайне простой и тривиальный код. Хотя это спорно — без бутылки не разобрать, чего там намешают в редюсерах и мидлварах. Выяснить, кто кого когда вызывает и почему — как правило квест.
Z>В ней говорится, что обращение из пользовательского интерфейса к бизнес-логике надо обязательно выполнять через Фасад.
Z>Вот картинка:
Фасад или не фасад, дело десятое. UI и БЛ нужно изолировать друг от друга. Обоснование — разная частота и причины изменений, т.е. можно и нужно менять эти вещи независимо друг от друга.
Ваш условный фасад 25 лет назад выглядел вот так
controller.execute(item.command, args); // обычно такой вызов прятался в инфраструктуру, вызывать его напрямую обычно не было нуждыУнутре контроллер найдет команду, которая реализует ну вот например "toggle.show.utilization"
связывание контролера и команд делается по имени, например, так
{
"toggle.show.utilization": "commands/ShowUtilization" // если хотите задавать через файл конфигурации, плагины итд
}Привязка команды к кнопке задавалась вот так
[
{"type": "button", "caption": "Toggle Pad", "command": "toggle.show.utilization", "args": ["$ctx"]}
]А вот собственно команда
@Handler("toggle.show.utilization") // можно было и так, но это для бесноватых любителей магии и неявного связывания
class ShowUtilization {
do(ctx) {
// вычисляем все изменения
const utilization = Utilization.calculate(ctx.model, ctx.config, app.config);
// применяем все изменения
const changes = model.apply(utilization);
return changes; // вернуть нужно подсказку для UI, что именно изменилось в модели, что бы проще было перерисовывать
}
undo(ctx) {
...
}
redo(ctx) {
....
}
}Бенефиты — ui знает только как вызвать контроллер. Контроллер знает только обобщенный интерфейс команд. Команда знает протокол работы с бл, но ничего про саму бл.
Сейчас, спустя 25 лет, это переизобретено под называнием Redux, см жээс фронтенд.
Ключевые отличиян
Было
controller.execute(item.command, args)controller вызывает команду а потом обновляет view — или шлет сигнал, или вызывает у каждой метод update
Стало
store.dispatch(item.action, args);view обновляется через store.subscribe(state => view.render(state))
+ вместо команд у вас редюсеры-мидлвары, приседания с иммутабельностью и конские издержки по перформансу и памяти как следствие. зато крайне простой и тривиальный код. Хотя это спорно — без бутылки не разобрать, чего там намешают в редюсерах и мидлварах. Выяснить, кто кого когда вызывает и почему — как правило квест.
Re: Фасад доменной модели - это God-объект?
Здравствуйте, zelenprog, Вы писали:
Z>В ней говорится, что обращение из пользовательского интерфейса к бизнес-логике надо обязательно выполнять через Фасад.
Z>Вот картинка:
Фасад или не фасад, дело десятое. UI и БЛ нужно изолировать друг от друга. Обоснование — разная частота и причины изменений, т.е. можно и нужно менять эти вещи независимо друг от друга, а так же высокая сложность одного из компонентов
Фасад нужен в т.ч. и для веб-приложений, см пример в конце. Всё дело в сложности — чем она выше, чем актуальнее изолироваться.
Ваш условный фасад 25 лет назад выглядел вот так
Унутре контроллер найдет команду, которая реализует ну вот например "toggle.show.utilization"
связывание контролера и команд делается по имени, например, так
Привязка команды к кнопке задавалась вот так
А вот собственно команда
Бенефиты — ui знает только как вызвать контроллер. Контроллер знает только обобщенный интерфейс команд. Команда знает протокол работы с бл, но ничего про саму бл.
Сейчас, спустя 25 лет, это переизобретено под называнием Redux, см жээс фронтенд.
Ключевые отличиян
Было
controller вызывает команду а потом обновляет view — или шлет сигнал, или вызывает у каждой метод update
Стало
view обновляется через store.subscribe(state => view.render(state))
+ вместо команд у вас редюсеры-мидлвары, приседания с иммутабельностью и конские издержки по перформансу и памяти как следствие. зато крайне простой и тривиальный код. Хотя это спорно — без бутылки не разобрать, чего там намешают в редюсерах и мидлварах. Выяснить, кто кого когда вызывает и почему — как правило квест.
Z>В ней говорится, что обращение из пользовательского интерфейса к бизнес-логике надо обязательно выполнять через Фасад.
Z>Вот картинка:
Фасад или не фасад, дело десятое. UI и БЛ нужно изолировать друг от друга. Обоснование — разная частота и причины изменений, т.е. можно и нужно менять эти вещи независимо друг от друга, а так же высокая сложность одного из компонентов
Фасад нужен в т.ч. и для веб-приложений, см пример в конце. Всё дело в сложности — чем она выше, чем актуальнее изолироваться.
Ваш условный фасад 25 лет назад выглядел вот так
controller.execute(item.command, args); // обычно такой вызов прятался в инфраструктуру, вызывать его напрямую обычно не было нуждыУнутре контроллер найдет команду, которая реализует ну вот например "toggle.show.utilization"
связывание контролера и команд делается по имени, например, так
{
"toggle.show.utilization": "commands/ShowUtilization" // если хотите задавать через файл конфигурации, плагины итд
}Привязка команды к кнопке задавалась вот так
[
{"type": "button", "caption": "Toggle Pad", "command": "toggle.show.utilization", "args": ["$ctx"]}
]А вот собственно команда
@Handler("toggle.show.utilization") // можно было и так, но это для бесноватых любителей магии и неявного связывания
class ShowUtilization {
do(ctx) {
// вычисляем все изменения
const utilization = Utilization.calculate(ctx.model, ctx.config, app.config);
// применяем все изменения
const changes = model.apply(utilization);
return changes; // вернуть нужно подсказку для UI, что именно изменилось в модели, что бы проще было перерисовывать
}
undo(ctx) {
...
}
redo(ctx) {
....
}
}Бенефиты — ui знает только как вызвать контроллер. Контроллер знает только обобщенный интерфейс команд. Команда знает протокол работы с бл, но ничего про саму бл.
Сейчас, спустя 25 лет, это переизобретено под называнием Redux, см жээс фронтенд.
Ключевые отличиян
Было
controller.execute(item.command, args)controller вызывает команду а потом обновляет view — или шлет сигнал, или вызывает у каждой метод update
Стало
store.dispatch(item.action, args);view обновляется через store.subscribe(state => view.render(state))
+ вместо команд у вас редюсеры-мидлвары, приседания с иммутабельностью и конские издержки по перформансу и памяти как следствие. зато крайне простой и тривиальный код. Хотя это спорно — без бутылки не разобрать, чего там намешают в редюсерах и мидлварах. Выяснить, кто кого когда вызывает и почему — как правило квест.