Программный код программного продукта нужно разделять на несколько слоев.
При этом получается, что Бизнес-слой — это самый внутренний слой, от которого зависят другие слои.
При этом сам Бизнес-слой получается независимым от других слоев.
Бывает ли такое, что бизнес-слой должен управлять поведением (логикой) другого слоя приложения?
Если ответ положительный и так делается, то как реализуется такое управление?
Как сделать внешний слой, о котором по сути Бизнес-логика ничего не знает, управляемым?
Здравствуйте, es3000, Вы писали:
E>Здравствуйте!
E>Программный код программного продукта нужно разделять на несколько слоев.
Есть такой шаблон — многоуровневая архитектура. При его применении да, выделяются слои. Но его же можно и не применять, потому "нужно" — под вопросом.
E>При этом получается, что Бизнес-слой — это самый внутренний слой, от которого зависят другие слои.
Как так? Что-то новое в делении на слои. E>При этом сам Бизнес-слой получается независимым от других слоев.
E>Бывает ли такое, что бизнес-слой должен управлять поведением (логикой) другого слоя приложения?
Обычно так и бывает, что BLL управляет DAL.
E>Если ответ положительный и так делается, то как реализуется такое управление? E>Как сделать внешний слой, о котором по сути Бизнес-логика ничего не знает, управляемым?
Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних.
Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
S>Есть такой шаблон — многоуровневая архитектура. При его применении да, выделяются слои. Но его же можно и не применять, потому "нужно" — под вопросом.
Начну с примера.
Лежит красное яблоко, помидор, огурец.
Их можно мысленно объединить в группы "фрукты", "овощи", "красные", и т. д.
Хотя лежат они вперемешку.
Также и с кодом.
Физически код может быть и не разделен на слои, то есть код написан "вперемешку".
Но логически этот код является частью какого-то слоя, в соответствии с решаемыми задачами.
Если физическое разделение кода по модулям соответствует логическому, то программа является хорошо спроектированной.
И от этого мы получаем много плюсов.
А если физическое разделение кода не соответствует логическому, то программа является плохо спроектированной.
И от этого мы имеем много минусов.
Так что, многоуровневую архитектуру можно и не применять.
Но (я повторяюсь) в любом случае, логически (мысленно) программный код в соответствии с решаемыми задачами можно отнести к какому-то слою.
Именно такое логическое разделение я имел ввиду, когда задавал вопрос.
E>>При этом получается, что Бизнес-слой — это самый внутренний слой, от которого зависят другие слои. S>Как так? Что-то новое в делении на слои.
А что не так?
E>>При этом сам Бизнес-слой получается независимым от других слоев. S>
Разве нет?
E>>Бывает ли такое, что бизнес-слой должен управлять поведением (логикой) другого слоя приложения? S>Обычно так и бывает, что BLL управляет DAL.
Правильнее сказать: BLL использует DAL, но не управляет.
Под управлением я имел ввиду влияние на алгоритмическое поведение.
Допустим в DAL заложен какой-то алгоритм извлечения данных из БД.
Может ли BLL влиять на этот алгоритм?
Или вообще подсунуть в DAL свой алгоритм?
S>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
Инверсия зависимости скорее предназначена для передачи данных обратно в верхний слой.
То есть нижний слой отрабатывает по своему "заложенному" в него алгоритму, а ответ возвращает через инверсию зависимостей.
Правильно я понимаю?
Здравствуйте, es3000, Вы писали:
S>>Есть такой шаблон — многоуровневая архитектура. При его применении да, выделяются слои. Но его же можно и не применять, потому "нужно" — под вопросом.
E>Начну с примера. E>Лежит красное яблоко, помидор, огурец. E>Их можно мысленно объединить в группы "фрукты", "овощи", "красные", и т. д. E>Хотя лежат они вперемешку.
E>Также и с кодом.
Замечательно. Пусть будет "лишний", "не работает", "васин".
E>Физически код может быть и не разделен на слои, то есть код написан "вперемешку". E>Но логически этот код является частью какого-то слоя, в соответствии с решаемыми задачами.
Т.е. для каждой строчки кода найдется слой или два, в которой она решает некую задачу. А что если строчка кода решает несколько задач? Кто определяет задачи? Напечатать отчет — это задача или нет?
E>Если физическое разделение кода по модулям соответствует логическому, то программа является хорошо спроектированной.
Я привел пример. "лишний", "не работает", "васин". Разнесли по модулям с соответствующими именами. Это хорошо спроектированная программа? E>И от этого мы получаем много плюсов.
Каких, например?
E>А если физическое разделение кода не соответствует логическому, то программа является плохо спроектированной. E>И от этого мы имеем много минусов.
E>Так что, многоуровневую архитектуру можно и не применять.
E>Но (я повторяюсь) в любом случае, логически (мысленно) программный код в соответствии с решаемыми задачами можно отнести к какому-то слою. E>Именно такое логическое разделение я имел ввиду, когда задавал вопрос.
"Такое логическое" разделение мне непонятно. Т.е. я не могу оперировать конкретным слоем БЛ в некотором "таком логическом" разделении...
E>>>При этом получается, что Бизнес-слой — это самый внутренний слой, от которого зависят другие слои. S>>Как так? Что-то новое в делении на слои.
E>А что не так?
Например, найдется слой, не зависящий от БЛ. Обычно это DAL, но я не знаю, как это устроено в "таком логическом" разделении.
E>>>При этом сам Бизнес-слой получается независимым от других слоев. S>>
E>Разве нет?
S>>Обычно так и бывает, что BLL управляет DAL.
E>Правильнее сказать: BLL использует DAL, но не управляет. E>Под управлением я имел ввиду влияние на алгоритмическое поведение.
Не понимаю, что такое влияние на алгоритмическое поведение.
E>Допустим в DAL заложен какой-то алгоритм извлечения данных из БД. E>Может ли BLL влиять на этот алгоритм?
Конечно. E>Или вообще подсунуть в DAL свой алгоритм?
Элементарно.
S>>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>>Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
E>Инверсия зависимости скорее предназначена для передачи данных обратно в верхний слой.
Зачем тут инверсия? E>То есть нижний слой отрабатывает по своему "заложенному" в него алгоритму, а ответ возвращает через инверсию зависимостей. E>Правильно я понимаю?
Это я уже не понимаю, о чем речь.
Здравствуйте, es3000, Вы писали:
S>>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>>Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
E>Инверсия зависимости скорее предназначена для передачи данных обратно в верхний слой. E>То есть нижний слой отрабатывает по своему "заложенному" в него алгоритму, а ответ возвращает через инверсию зависимостей. E>Правильно я понимаю?
Инверсия зависимостей не означает инверсные зависимости. Она относится только к фазе инициализации программы, когда BLL получает экземпляры нужных ему DAL. В этом и состоит инверсия — он эти экземпляры получает извне, а не создает сам.
BLL вызывает DAL самым обыкновенным образом, через вызовы функций. Если требуется более сложное поведение, можно добавить новый метод в DAL или расширить API DAL конфигурацией или паттерном Стратегия.
Здравствуйте, es3000, Вы писали:
S>>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>>Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
E>Инверсия зависимости скорее предназначена для передачи данных обратно в верхний слой. E>То есть нижний слой отрабатывает по своему "заложенному" в него алгоритму, а ответ возвращает через инверсию зависимостей. E>Правильно я понимаю?
Я бы не стал весь этот подход называть "инверсией зависимости", т.к. это лишь технический прием представения абстрактных сущностей.
В более широком смысле разделение на слои выполняется введением абстракций, которыми манипулирует слой вышестоящего уровня, а реализация этих абстракций относится к нижележащим слоям.
В идеале определении абстракции должно фиксировать необходимые требования и оставлять допустимые степени свободы.
В зависимости от используемых инструментов разработки, это достигается определением контрактов, проверкой пред- и пост-условий, заданием очевидно интерпретируемых имен, написанием комментариев в коде и документации.
Например, мы делаем текстовый редактор. На уровне модели умеем хранить буковки, делать поиск и замену.
Наряду с конкретными типа FindRequest, ReplaceRequest на уровне модели может быть определен абстрактный интерфейс ISpellChecker.
Реализация конкретных проверщиков орфографии для разных языков может быть реализована за пределами модели и даже за пределами приложения — в плагине.
S>Замечательно. Пусть будет "лишний", "не работает", "васин".
Можно и так разделить.
Только какой толк от такого разделения?
S>Т.е. для каждой строчки кода найдется слой или два, в которой она решает некую задачу. А что если строчка кода решает несколько задач? Кто определяет задачи? Напечатать отчет — это задача или нет?
Задачи определяются целью программы.
Напечатать отчет — конечно это задача — если это входит в назначение программы.
S>Я привел пример. "лишний", "не работает", "васин". Разнесли по модулям с соответствующими именами. Это хорошо спроектированная программа?
Это плохо спроектированная программа.
Так как разделение на модули выполняется по критерию соответствия решаемым задачам, а не каким-то другим критериям (по автору, по полезности).
E>>И от этого мы получаем много плюсов. S>Каких, например?
Не вижу смысла заниматься плагиатом.
Пару книжек пролистайте по проектированию программ — там все написано.
S>Например, найдется слой, не зависящий от БЛ. Обычно это DAL, но я не знаю, как это устроено в "таком логическом" разделении.
Не согласен.
DAL как раз проектируется так, чтобы выдавать то, что нужно для BLL.
S>Не понимаю, что такое влияние на алгоритмическое поведение.
Алгори́тм (лат. algorithmi — от арабского имени математика Аль-Хорезми[1]) — конечная совокупность точно заданных правил решения произвольного класса задач или набор инструкций, описывающих порядок действий исполнителя для решения некоторой задачи.
Допустим, в каком то слое (пусть это будет DAL) заложен какой-то алгоритм — то есть "...набор инструкций, описывающих порядок действий для решения некоторой задачи ...".
Мы в Бизнес-слое используем этот слой и хотим изменить этот "порядок действий".
Вот это и есть влияние на алгоритмическое поведение.
S>>>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>>>Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые доступны в низлежащем слое.
Наверно, правильнее сказать так: "Управление в таком случае осуществляется через инверсию зависимостей, т.е. через интерфейсы, которые предоставляются из низлежащего слоя".
Правильно?
scf>Инверсия зависимостей не означает инверсные зависимости. Она относится только к фазе инициализации программы, когда BLL получает экземпляры нужных ему DAL. В этом и состоит инверсия — он эти экземпляры получает извне, а не создает сам.
А кто создает эти экземпляры DAL, которые будут подсунуты в BLL?
scf>BLL вызывает DAL самым обыкновенным образом, через вызовы функций. Если требуется более сложное поведение, можно добавить новый метод в DAL или расширить API DAL конфигурацией или паттерном Стратегия.
А если используется асинхронное взаимодействие верхнего и нижнего уровней?
Верхний уровень отправил сообщение.
Как верхний уровень потом получит ответ от нижнего уровня?
Q>Например, мы делаем текстовый редактор. На уровне модели умеем хранить буковки, делать поиск и замену. Q>Наряду с конкретными типа FindRequest, ReplaceRequest на уровне модели может быть определен абстрактный интерфейс ISpellChecker. Q>Реализация конкретных проверщиков орфографии для разных языков может быть реализована за пределами модели и даже за пределами приложения — в плагине.
ISpellChecker — это же и есть инверсия зависимости?
Здравствуйте, es3000, Вы писали:
S>>Замечательно. Пусть будет "лишний", "не работает", "васин".
E>Можно и так разделить. E>Только какой толк от такого разделения?
Если отталкиваться от толка, то можно найти ответ и на вопрос, по какому принципу код делится на слои и располагается (выше/ниже). А так же, почему BLL будет видеть DAL, но не наоборот.
S>>Т.е. для каждой строчки кода найдется слой или два, в которой она решает некую задачу. А что если строчка кода решает несколько задач? Кто определяет задачи? Напечатать отчет — это задача или нет?
E>Задачи определяются целью программы. E>Напечатать отчет — конечно это задача — если это входит в назначение программы.
Что такое цель программы? Нарубить бабла?
S>>Я привел пример. "лишний", "не работает", "васин". Разнесли по модулям с соответствующими именами. Это хорошо спроектированная программа?
E>Это плохо спроектированная программа. E>Так как разделение на модули выполняется по критерию соответствия решаемым задачам, а не каким-то другим критериям (по автору, по полезности).
Так модули или слои? Это не одно и то же. В заголовке темы обозначены слои.
E>>>И от этого мы получаем много плюсов. S>>Каких, например?
E>Не вижу смысла заниматься плагиатом. E>Пару книжек пролистайте по проектированию программ — там все написано.
Читал и не пару. Просто я привык принимать решения для достижения определенных целей, а не потому, что так в книжке написано.
S>>Например, найдется слой, не зависящий от БЛ. Обычно это DAL, но я не знаю, как это устроено в "таком логическом" разделении.
E>Не согласен. E>DAL как раз проектируется так, чтобы выдавать то, что нужно для BLL.
Это противоречит чему-то?
S>>Не понимаю, что такое влияние на алгоритмическое поведение.
E>
E>Алгори́тм (лат. algorithmi — от арабского имени математика Аль-Хорезми[1]) — конечная совокупность точно заданных правил решения произвольного класса задач или набор инструкций, описывающих порядок действий исполнителя для решения некоторой задачи.
А что такое "алгоритмическое поведение"?
E>Допустим, в каком то слое (пусть это будет DAL) заложен какой-то алгоритм — то есть "...набор инструкций, описывающих порядок действий для решения некоторой задачи ...".
Допустим E>Мы в Бизнес-слое используем этот слой и хотим изменить этот "порядок действий".
допустим, бизнес-слой указывает критерий выборки данных... E>Вот это и есть влияние на алгоритмическое поведение.
Вот это и есть, выходит, ситуация, "что бизнес-слой должен управлять поведением (логикой) другого слоя приложения?"
Скажем точнее — назначение программы.
S>Так модули или слои? Это не одно и то же. В заголовке темы обозначены слои.
Да, вопрос про слои.
Но в смысле данного вопроса не вижу особой разницы: и слои зависят друг от друга, и модули зависят друг от друга.
И слой может управлять другим слоем.
И модуль может управлять другим модулем.
E>>Пару книжек пролистайте по проектированию программ — там все написано. S>Читал и не пару. Просто я привык принимать решения для достижения определенных целей, а не потому, что так в книжке написано.
Вот эти определенные цели в книжках и указаны.
Хочется, чтобы программа, кроме своего назначения, еще соответствовала и этим целям проектирования.
S>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>Например, найдется слой, не зависящий от БЛ. Обычно это DAL... E>DAL как раз проектируется так, чтобы выдавать то, что нужно для BLL. S>Это противоречит чему-то?
E>>Мы в Бизнес-слое используем этот слой и хотим изменить этот "порядок действий". S>допустим, бизнес-слой указывает критерий выборки данных... E>>Вот это и есть влияние на алгоритмическое поведение. S>Вот это и есть, выходит, ситуация, "что бизнес-слой должен управлять поведением (логикой) другого слоя приложения?"
То есть управлением поведения можно только через установку параметров.
Так получается?
Здравствуйте, es3000, Вы писали: E>ISpellChecker — это же и есть инверсия зависимости?
Да, как технический прием.
В более общем смысле — это абстракция, которую проектировщик выделил и наделил определенным смыслом в рамках решения задачи создания текстового редактора.
Здравствуйте, es3000, Вы писали:
S>>Так модули или слои? Это не одно и то же. В заголовке темы обозначены слои.
E>Да, вопрос про слои.
E>Но в смысле данного вопроса не вижу особой разницы: и слои зависят друг от друга, и модули зависят друг от друга. E>И слой может управлять другим слоем. E>И модуль может управлять другим модулем.
Так и с методами(функциями) тоже нет особой разницы. Функции зависят друг от друга и управляют друг другом. Может о функциях поговорим?
E>>>Пару книжек пролистайте по проектированию программ — там все написано. S>>Читал и не пару. Просто я привык принимать решения для достижения определенных целей, а не потому, что так в книжке написано.
E>Вот эти определенные цели в книжках и указаны. E>Хочется, чтобы программа, кроме своего назначения, еще соответствовала и этим целям проектирования.
Здравствуйте, es3000, Вы писали:
S>>Слои для того и придумали, что бы изолировать слои верхнего уровня от нижнего, т.е. что бы нижние не знали о верхних. S>>Например, найдется слой, не зависящий от БЛ. Обычно это DAL... E>>DAL как раз проектируется так, чтобы выдавать то, что нужно для BLL. S>>Это противоречит чему-то?
E>Да, противоречит. E>Так как внутренним считается слой BLL, а DAL по отношению к нему считается внешним. E>https://habr.com/ru/company/mobileup/blog/335382/
У Мартина зависимость BLL от DAL инвертирована, BLL не видит DAL напрямую, вместо этого обращается к Repositories. При этом BLL все еще может формировать критерии для выборки, т.е. управлять инструкциями, которые выполняет DAL.
E>Значит, DAL должен не зависеть от BLL.
У Мартина, но не вообще. E>Но как же он не зависит, если выдает данные в формате BLL?
Он выдает Entity, которое является общим для нескольких слоев. В точности как integer или string.
Здравствуйте, es3000, Вы писали:
S>>Вот это и есть, выходит, ситуация, "что бизнес-слой должен управлять поведением (логикой) другого слоя приложения?"
E>То есть управлением поведения можно только через установку параметров. E>Так получается?
Именно так и получается, если учесть что в качестве параметра можно передавать и инструкции в том числе, которые будут выполнены в том месте, куда были переданы.
S>Так и с методами(функциями) тоже нет особой разницы. Функции зависят друг от друга и управляют друг другом. Может о функциях поговорим?
S>Хорошо. Когда хочется, аргументация бесполезна.
Зачем к словам цепляться?
Смысл то понятен.
Ну скажем не "хочется", а "требуется для сохранения возможности поддержки и дальнейшего развития приложения".
И где хоть какая-то аргументация?
Ты даже тезис никакой не высказал, аргументировать пока еще нечего.
Суть та же самая: сделать код одного слоя независимым от других слоев.
Причем это даже не архитектура, а общие формулировки.
S>У Мартина зависимость BLL от DAL инвертирована, BLL не видит DAL напрямую, вместо этого обращается к Repositories. При этом BLL все еще может формировать критерии для выборки, т.е. управлять инструкциями, которые выполняет DAL.
S>У Мартина, но не вообще.
Просто подход Мартина — внес новую идею в разделение слоев.
За счет этого это разделение слоев стало еще лучше.
Ну это как постепенное развитие например бензиновых двигателей.
Ясное дело, что современные двигатели во много превосходят двигатели 50-летней давности.
Так и подход к разделению слоев.
Подход Мартина — более конкретен чем предыдущие общие формулировки.
S>>Так и с методами(функциями) тоже нет особой разницы. Функции зависят друг от друга и управляют друг другом. Может о функциях поговорим?
S>>Хорошо. Когда хочется, аргументация бесполезна.
E>Зачем к словам цепляться? E>Смысл то понятен. E>Ну скажем не "хочется", а "требуется для сохранения возможности поддержки и дальнейшего развития приложения".
Если взять довольно простое приложение и вкорячить в него правильную архитектуру, оно внезапно перестанет быть простым, поддерживать и развивать его станет сложнее. Потому, не всякому приложению это полезно.
E>И где хоть какая-то аргументация? E>Ты даже тезис никакой не высказал, аргументировать пока еще нечего.
Аргументация на что? Ты послал меня книжки полистать и найти там тезисы. Им оппонировать?