Re[21]: Бизнес-слой управляет другим слоем
От: samius Япония http://sams-tricks.blogspot.com
Дата: 27.05.19 11:55
Оценка:
Здравствуйте, es3000, Вы писали:


S>>В ответ на твой вопрос, в котором не упоминалось ООП.


E>А почему ты предположил, что я собираюсь решать задачу не на ООП?


Причем тут ты? Ты спросил, что есть "для богатых".
Re[3]: Бизнес-слой управляет другим слоем
От: Stalker. Австралия  
Дата: 27.05.19 22:35
Оценка:
Здравствуйте, es3000, Вы писали:

E>Ты говоришь про "сервис". Под "сервисом" ты имеешь ввиду сервисный слой?

E>По другому он кажется называется "Application Layer".
E>Это про него идет речь?

да, это слой который оркестрирует другими слоям, workflow, service — точное название не имеет особого значения. В данном примере немного неудачно выбрано назначение бизнес-логики, сохранение файла будет ответственностью DAL (хотя для редактора это скорее надо будет назвать как-то по-другому), именно он будет кидать исключения о существующем файле, недоступности папки на запись и прочее, а бизнес слой в редакторе будет управлять всяким форматированием, проверкой синкаксиса и прочее.
Сервис получит ссылки на бизнес-обьекты, DAL (через интерфейс что-бы замокить можно было для тестов) и (возможно) UI.
Re[17]: Бизнес-слой управляет другим слоем
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.05.19 03:35
Оценка: 3 (2)
E>Можете предложить какой-то вариант для примера?
Очень трудно предлагать вариант, не имея конкретной задачи. Потому что проектирование — оно всегда идёт от задачи. Иначе опять получаем культ карго: по инструкции, разработанной для паровоза, собирается велосипед. Или наоборот.
В целом лично у меня всегда идёт перекос в сторону 3-tier архитектуры — когда над слоем persistence живёт логика приложения, а весь UI спроектирован в виде клиента, который общается с application tier через API. При этом в API границы транзакций совпадают с границами методов. Любой "сценарий" реализуется в виде набора атомарных шагов, каждый из которых можно выполнить независимо.
Всё взаимодействие tier-ов идёт строго в одном направлении: сверху вниз. Application tier не имеет возможностей типа "а давайте-ка покажем модальный диалог" или "сделаем кнопку save недоступной". Максимум интерактива — это возврат 400 Bad Request со структурированным body, по которому клиент может понять, что он сделал не так.
Если хочется иметь оповещения за пределами рамок текущей операции, то для этого делается специальный метод ReceiveNotification(since: notificationMarker), которого клиент периодически поллит и показывает нотификации в удобном ему стиле.

Это всё сильно отражается не столько на структуре слоёв, сколько на устройстве логики приложения. Если в Delphi-event-handler-style можно было просто начать операцию, и ветвиться по ней в процессе общения как со storage, так и с UI, то в таком подходе так делать нельзя. Нужно всё время думать о том, что может пойти не так, и как продолжить операцию в случае чего. То есть, скажем, "заявка на перевод" из эфемерной формы диалога превращается в полноценный объект, хранящийся в базе. У него появляются этапы конструирования, правила перевода из одного состояния в другое, и прочие штуки.
Иногда такой подход приводит вообще к замене ядра приложения на workflow management system типа jira, где вся логика сводится к описанию атрибутов сущности, состояний сущности, и правил перехода между этими состояниями в зависимости от значений атрибутов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 10:04
Оценка:
S>да, это слой который оркестрирует другими слоям, workflow, service — точное название не имеет особого значения. В данном примере немного неудачно выбрано назначение бизнес-логики, сохранение файла будет ответственностью DAL (хотя для редактора это скорее надо будет назвать как-то по-другому), именно он будет кидать исключения о существующем файле, недоступности папки на запись и прочее,
S>а бизнес слой в редакторе будет управлять всяким форматированием, проверкой синкаксиса и прочее.
S>Сервис получит ссылки на бизнес-обьекты, DAL (через интерфейс что-бы замокить можно было для тестов) и (возможно) UI.

Получается, что это слой "Сервис" должен выдавать пользователю запрос на дальнейшую обработку файла.
То есть он должен работать с UI.
Тут два вопроса:

1) Этот код — запрос на дальнейшую обработку файла — это часть логики приложения.
Это не часть UI.
Получается, что важный для логики работы код находится вне бизнес-слоя, в каком-то другом слое.
Мне кажется это не хорошо.

2) На всех схемах дизайна приложения слой "Сервис" рисуется подчиненным по отношению к UI.
То есть согласно этим схемам не "Сервис" управляет пользовательским интерфейсом, а пользовательский интерфейс управляет "Сервисом".
Ты же предлагаешь сделать наоборот.
Тогда, наш "Сервис" будет супер-главным слоем, а все остальные ему подчинены.
Нету тут противоречия?
Re[18]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 11:06
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В целом лично у меня всегда идёт перекос в сторону 3-tier архитектуры — когда над слоем persistence живёт логика приложения, а весь UI спроектирован в виде клиента, который общается с application tier через API. При этом в API границы транзакций совпадают с границами методов. Любой "сценарий" реализуется в виде набора атомарных шагов, каждый из которых можно выполнить независимо.

Поддерживаю.

От себя добавлю, что оформление бизнес-логики в виде черного ящика с API очень удобно для написания юнит тестов.
И, как раз, при написании юнит тестов, где никакого UI нет, прекрасно выявляются "плохие" места логики.

Бывают случаи, когда бизнес-логика (сервер), требует выбора или подтверждения какого-то действия клиентом
(это может быть как интерактивный клиент с UI, так и что-то другое).
Я для таких случаев применял API из пары функций:
<требуемые действия> QueryActions(<запрашиваемые действия>)
PerformActions(<подтвержденные действия>)

Здесь "действия" могут быть битовыми флагами, списком строк или еще чем-то в этом роде.

Предполагается, что клиент заранее не знает какие действия надо выполнять (например, сохранить изменения в файл).
Сначала вызывается QueryActions(маска — "Все действия"), она возвращает — "сохранение в файл".
Т.е. модуль бизнес-логики сообщает клиенту свои хотелки.
Далее клиент может показать UI (если клиент с UI) и вызвать (или не вызывать) PerformActions("сохранение в файл").

Вот такой протокол взаимодействия я применял для избавления от блокирующего callback из модуля бизнес-логики.
Подход не лишен недостатков. Например, нет транзакционности, т.е. информация возвращенная QueryActions может протухнуть ко времени вызова PerformActions.
С этим надо что-то решать, опираясь на специфику задачи. Серебряной пули нет.
Re[18]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 11:21
Оценка:
S>Это всё сильно отражается не столько на структуре слоёв, сколько на устройстве логики приложения. Если в Delphi-event-handler-style можно было просто начать операцию, и ветвиться по ней в процессе общения как со storage, так и с UI,
S>то в таком подходе так делать нельзя. Нужно всё время думать о том, что может пойти не так, и как продолжить операцию в случае чего. То есть, скажем, "заявка на перевод" из эфемерной формы диалога превращается в полноценный объект, хранящийся в базе.
S>У него появляются этапы конструирования, правила перевода из одного состояния в другое, и прочие штуки.

Тогда получается, что оперировать этими "этапами" и "правилами перевода" должен какой-то код более высокого уровня, какой-то отдельный слой.
Этот слой должен реализовать логику, которая использует "этапы" и "правила перевода" бизнес-объекта.
То есть, это должен быть достаточно "умный" слой.
Ведь без него по сути и приложения никакого не получится, даже несмотря на наличие отлично спроектированного и реализованного бизнес-слоя (но не имеющего этой логики).
Причем, этот слой не зависит от конкретного UI, DAL и других внешних слоев, так как он реализует только логику.

Получается, что вся суть приложения разделена между двумя слоями:
— Бизнес-слой реализует этапы, состояния и правила бизнес-объектов
— "Умный" слой, который реализует логику приложения и оперирует бизнес-слоем.

Правильно я рассуждаю?

Если да, то тогда есть такие вопросы:
1) Что это за "Умный" слой? Как его обычно называют?
2) На каком уровне "иерархии" слоев он находится?
По идее это должен быть самый высокий уровень, так как он оперирует также и другими слоями в том числе и UI.
Re[19]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 11:40
Оценка:
Q>Бывают случаи, когда бизнес-логика (сервер), требует выбора или подтверждения какого-то действия клиентом
Q>(это может быть как интерактивный клиент с UI, так и что-то другое).
Q>Я для таких случаев применял API из пары функций:
Q>
Q><требуемые действия> QueryActions(<запрашиваемые действия>)
Q>PerformActions(<подтвержденные действия>)
Q>

Q>Здесь "действия" могут быть битовыми флагами, списком строк или еще чем-то в этом роде.

Идея понятна.

Q>Предполагается, что клиент заранее не знает какие действия надо выполнять (например, сохранить изменения в файл).

Q>Сначала вызывается QueryActions(маска — "Все действия"), она возвращает — "сохранение в файл".

А кто вызывает QueryActions?
Клиент?
Если клиент, тогда зачем и в какой момент он вызывает эту функцию?

Q>Т.е. модуль бизнес-логики сообщает клиенту свои хотелки.

Q>Далее клиент может показать UI (если клиент с UI) и вызвать (или не вызывать) PerformActions("сохранение в файл").

Для выполнения этого действия надо передать параметры.
Как это делается?
Re[20]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 13:29
Оценка: 1 (1)
Здравствуйте, es3000, Вы писали:
E>А кто вызывает QueryActions?
E>Клиент?
E>Если клиент, тогда зачем и в какой момент он вызывает эту функцию?
Да, если под клиентом понимается "тот, кто использует API модуля бизнес логики".

Q>>Т.е. модуль бизнес-логики сообщает клиенту свои хотелки.

Q>>Далее клиент может показать UI (если клиент с UI) и вызвать (или не вызывать) PerformActions("сохранение в файл").

E>Для выполнения этого действия надо передать параметры.

E>Как это делается?
Псевдокод:
filename = "foo.dat";
response = QueryMyFileActions(filename, ActionType::Save); // есть ли вопросы по поводу сохранения файла "foo.dat"?
if (response.has(ActionResponse::Overwrite)) // требуется перезапись файла
 if (!QuestionUI(filename, ActionResponse::Overwrite)) // показываем MessageBox
   return; // пользователь отказался от перезаписи
try
{
  PerformMyFileAction(filename, ActionType::Save); // выполняем сохранение
}
catch(ex)
{
  ErrorUI(ex.msg()); // не шмогла...
}
Re: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 13:34
Оценка:
E>Как сделать внешний слой, о котором по сути Бизнес-логика ничего не знает, управляемым?

Придумал вот такой пример — игра, например, в шахматы пользователя с компьютером.
Понятно, что пользователь взаимодействует с программой через интерфейс.
Когда ход делает человек, то все нужные функции (в том числе и бизнес-логики) инициируются событиями пользовательского интерфейса.

А во время хода компьютера бизнес-логика должна инициировать действие с пользовательским интерфейсом.
Но у бизнес-логики нет прямого взаимодействия с интерфейсом.
Вот где должен располагаться код обработки хода компьютера и, как организуется последующее взаимодействие с пользовательским интерфейсом?
Re[18]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 13:36
Оценка:
S>Очень трудно предлагать вариант, не имея конкретной задачи.

Придумал пример — игра пользователя с компьютером в шахматы.
Чтобы здесь ветку не раздувать, написал этот пример в новой ветке:
http://rsdn.org/forum/design/7456335.1
Автор: es3000
Дата: 28.05.19
Re[21]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 13:40
Оценка:
Q>Да, если под клиентом понимается "тот, кто использует API модуля бизнес логики".

Q>Псевдокод:

Q>
Q>filename = "foo.dat";
Q>response = QueryMyFileActions(filename, ActionType::Save); // есть ли вопросы по поводу сохранения файла "foo.dat"?
Q>if (response.has(ActionResponse::Overwrite)) // требуется перезапись файла
Q> if (!QuestionUI(filename, ActionResponse::Overwrite)) // показываем MessageBox
Q>   return; // пользователь отказался от перезаписи
Q>try
Q>{
Q>  PerformMyFileAction(filename, ActionType::Save); // выполняем сохранение
Q>}
Q>catch(ex)
Q>{
Q>  ErrorUI(ex.msg()); // не шмогла...
Q>}
Q>


И в какой момент срабатывает этот код?
Re[19]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 13:56
Оценка:
Здравствуйте, es3000, Вы писали:
E>То есть, это должен быть достаточно "умный" слой.
E>Ведь без него по сути и приложения никакого не получится, даже несмотря на наличие отлично спроектированного и реализованного бизнес-слоя (но не имеющего этой логики).
E>Причем, этот слой не зависит от конкретного UI, DAL и других внешних слоев, так как он реализует только логику.

Если мы говорим об UI-приложении, то этот слой — наш пользователь.
Это пользователь дергает за ниточки UI, которые в конечном счете ведут к функциям бизнес-логики.

Также это может быть юнит тест, который моделирует различные сценарии работы пользователя, или какой-то скрипт/макрос, который написал опытный пользователь.
Например, в Excel пользователь может воздействовать на модель (документ) через UI, а может написать макрос на VB, который работает с моделью через тот же API (OLE Automation).

E>Получается, что вся суть приложения разделена между двумя слоями:

E>- Бизнес-слой реализует этапы, состояния и правила бизнес-объектов
E>- "Умный" слой, который реализует логику приложения и оперирует бизнес-слоем.

E>Если да, то тогда есть такие вопросы:

E>1) Что это за "Умный" слой? Как его обычно называют?
E>2) На каком уровне "иерархии" слоев он находится?
E>По идее это должен быть самый высокий уровень, так как он оперирует также и другими слоями в том числе и UI.

Насколько пользователи бывают умные и наоборот, существуют разные точки зрения.
Мой опыт подсказывает, что все что можно испортить и где напортачить, они сделают...
Поэтому, разработчику следует априори рассматривать "умный слой", как обезьяну с гранатой.

Если приложение не такого рода, что "в любой момент творю, что хочу", то надо выделять некие control flow, ориентированные на решение большой задачи.
Выполнение очередного шага большой задачи переводит объекты бизнес-логики из одного состояния в другое.
При выполнении большой задачи могут возникать циклические шаги, например, ввод информации для нескольких элементов данных.
UI может выстраиваться с учетом решения больших задач (привет от мастера-wizard'a).
В каких-то случаях это может оказаться невозможными или очень трудоемким — тогда следование логике большой задачи целиком возлагается на пользователя (см. User's Guide стр. 55555).

Пример большой задачи — расчет з/п на предприятии.
Прежде чем сделать платежную ведомость, надо ввести отработанные дни, больничные, рассчитать налоги — все это шаги большой задачи.
Re[22]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 13:58
Оценка:
Здравствуйте, es3000, Вы писали:

E>И в какой момент срабатывает этот код?

В UI обработчике OnSaveMyFile().
Re[2]: Бизнес-слой управляет другим слоем
От: Ромашка Украина  
Дата: 28.05.19 14:11
Оценка:
Здравствуйте, es3000, Вы писали:
E>>Как сделать внешний слой, о котором по сути Бизнес-логика ничего не знает, управляемым?
E>Придумал вот такой пример — игра, например, в шахматы пользователя с компьютером.

Я тебе другой пример предложу — микроволновку. Вот ты положил в нее пиццу и поставил её на разогрев. Глупо ожидать от микроволновки, что она положит тебе кусок пиццы в рот и разжует. Микроволновка тобой не управляет. Это твои проблемы, когда и как ты вспомнишь про пиццу в микроволновке, достанешь ты ее сам или попросишь коллегу, съешь пиццу сам или угостишь симпатишную тестеровщицу. Микроволновке пофиг. Максимум, что микроволновка может — пискнуть и выключиться.

Так вот, микроволновка это и есть твой BLL. Не пытайся всунуть в неё несвойственные ей функции, это как минимум странно.


Всё, что нас не убивает, ещё горько об этом пожалеет.
Re[20]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 14:37
Оценка:
Q>Если мы говорим об UI-приложении, то этот слой — наш пользователь.

Нет, я имел ввиду не пользователя.

Q>Если приложение не такого рода, что "в любой момент творю, что хочу", то надо выделять некие control flow, ориентированные на решение большой задачи.


Вот что я имел ввиду под "умным слоем" — слой control flow.

Q>Выполнение очередного шага большой задачи переводит объекты бизнес-логики из одного состояния в другое.

Q>При выполнении большой задачи могут возникать циклические шаги, например, ввод информации для нескольких элементов данных.
Q>UI может выстраиваться с учетом решения больших задач (привет от мастера-wizard'a).

Вот я и веду речь как раз о таких "умных" control flow, которые должны управлять wizard-ом.

Q>Пример большой задачи — расчет з/п на предприятии.

Q>Прежде чем сделать платежную ведомость, надо ввести отработанные дни, больничные, рассчитать налоги — все это шаги большой задачи.

Только я считал (да и сейчас считаю), что логика этих control flow — это чисто логика имеющая отношение к бизнес-слою.
Расчет зарплаты — типичный пример. Ну разве это не бизнес-логика?
Получается, что есть бизнес-логика, которая завязана на действия пользователя.
Которая диктует пользователю — что надо делать.
То есть бизнес-логика управляет пользовательским интерфейсом.

Вот в чем мой вопрос.
В каком слое надо делать эту логику? Как она должна управлять взаимодействием с пользователем, оставаясь при этом независимой от интерфейса?

Вот еще придумал пример — про игру в шахматы.
Вот здесь написал:
http://rsdn.org/forum/design/7456335.1
Автор: es3000
Дата: 28.05.19
Re[23]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 14:41
Оценка:
E>>И в какой момент срабатывает этот код?
Q>В UI обработчике OnSaveMyFile().

Так ведь тогда получается, что мы важную для бизнес-слоя логику просто переложили на UI!
Но ведь это неправильно.
Re[21]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 14:47
Оценка:
Здравствуйте, es3000, Вы писали:

E>Вот я и веду речь как раз о таких "умных" control flow, которые должны управлять wizard-ом.


Здесь прямо про это написал:
http://rsdn.org/forum/design/7456394.1
Автор: qaz77
Дата: 28.05.19
Re[3]: Бизнес-слой управляет другим слоем
От: es3000  
Дата: 28.05.19 14:53
Оценка:
Р>Я тебе другой пример предложу — микроволновку. Вот ты положил в нее пиццу и поставил её на разогрев. Глупо ожидать от микроволновки, что она положит тебе кусок пиццы в рот и разжует. Микроволновка тобой не управляет.

Я говорю не про управление человеком.
А про управление пользовательским интерфейсом со стороны логики приложения.

Микроволновка хотя бы пропищит "забирай свою пицу" и будет ждать ответа.
И компьютер в шахматной партии сделает ход и будет ждать ответа.
То есть они в любом случае дадут знать пользовательскому интерфейсу — что надо сделать на следующем шаге.

Р>Микроволновке пофиг. Максимум, что микроволновка может — пискнуть и выключиться.


Вот этот писк — это и есть действия пользовательского интерфейса микроволновки.
И этот писк был инициирован ее логикой работы: закончила греть — пискни.

Р>Так вот, микроволновка это и есть твой BLL.


Нет. Микроволновка — это UI + BLL.
UI — Это мигающие лампочки и писки. И они включаются тогда когда посчитает нужным BLL микроволновки.

Это полностью соотвествует моему вопросу.
Компьютер (бизнес-логика) придумал ход — говорит интерфейсу — нарисуй на шахматной доске, спроси у пользователя ответ.
Или в случае визарда: бизнес-логика что-то обрабатывает, ей не хватает данных, она говорит интерфейсу — запроси у пользователя дополнительные данные.
Отредактировано 28.05.2019 14:55 es3000 . Предыдущая версия .
Re[21]: Бизнес-слой управляет другим слоем
От: qaz77  
Дата: 28.05.19 15:18
Оценка: +1
Здравствуйте, es3000, Вы писали:
Q>>Пример большой задачи — расчет з/п на предприятии.
Q>>Прежде чем сделать платежную ведомость, надо ввести отработанные дни, больничные, рассчитать налоги — все это шаги большой задачи.

E>Только я считал (да и сейчас считаю), что логика этих control flow — это чисто логика имеющая отношение к бизнес-слою.

E>Расчет зарплаты — типичный пример. Ну разве это не бизнес-логика?

Вводить исходные данные для расчета з/п могут несколько человек в течении нескольких дней, у каждого свой UI в определенном состоянии, который они закрывают в конце рабочего дня.
Т.е. состояние объектов бизнес-логики пассивно по отношению к UI.
Пользователь воздействует на UI, UI вызывает функции BL API (прямо или через какой-нибудь контроллер).

Когда в UI открыли какой-то диалог, ввели данные и нажали ОК, то изменяется состояние объектов бизнес-логики (и состояние БД, в конечном счете).
Если происходит нарушение условий бизнес-логики, то генерируется ошибка.
Чтобы UI-диалог не закрывался при заведомо ошибочных условиях, у модуля бизнес-логики должен быть API валидации данных.

E>Получается, что есть бизнес-логика, которая завязана на действия пользователя.

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

E>Которая диктует пользователю — что надо делать.

Пользователь делает, что хочет, но если это противоречит правилам бизнес логики, то получает ошибку.

E>То есть бизнес-логика управляет пользовательским интерфейсом.

Нет. Бизнес-логика прекрасно живет без всякого UI, ей не важно кто дергает API.
Разработчик для создания дружественного пользователю UI может предусмотреть дополнительное API для подсказок по control flow и валидации данных.
При этом UI будет руководствоваться тем, что вернули функции BL API.
Поэтому правильно говорить, что реализация UI завязана/зависит от BL API.
BL не управляет UI, это UI через BL API отображает и изменяет состояние объектов бизнес логики.
Re[4]: Бизнес-слой управляет другим слоем
От: Ромашка Украина  
Дата: 28.05.19 16:30
Оценка:
Здравствуйте, es3000, Вы писали:
E>Нет. Микроволновка — это UI + BLL.

Не дроби мне слои. Микроволновка — BLL, человек — UI.

E>Компьютер (бизнес-логика) придумал ход — говорит интерфейсу — нарисуй на шахматной доске, спроси у пользователя ответ.


Ничего подобного интерфейсу никто не говорит. Не хватало еще, чтобы мне микроволновка указывала. Что рисовать — решает UI. Может он в это время пользователю рекламу гугла крутит? Какой ход, какое рисование — бабло важнее. В примере с микроволновкой, например, ты с девушкой сексом занимаешься — да пусть хоть обпищится и обмигается своими лампочками.

Максимум, что может BLL — пискнуть и помигать лампочкой. В подавляющем большинстве случаев даже этого никто не делает — путь UI сам разбирается, что и когда рисовать пользователю. Потому что UI на компе пользователя, а BLL на сервере который вообще нифига не знает, что у пользователя творится.


Всё, что нас не убивает, ещё горько об этом пожалеет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.