бизнес логика приложения это
Организация бизнес-логики корпоративных приложений. Какие возможны варианты?
В этой статье мы попытаемся найти ответ на вопрос, обозначений в заголовке. А также порассуждаем на тему возможности универсального решения на все случае жизни.
Три типовых решения при работе с бизнес-логикой по Фаулеру
Сколько типовых решений на самом деле?
Понятно, что речь не идет о чистой реализации той или иной парадигмы. Всегда есть компромиссы, вызванные ограничениями используемых технологий. Если вы пишете на C# или Java, объектно-ориентированных языках по своей природе, то это совсем не значит, что ваш код автоматически становится объектно-ориентированным. Всю программу вполне могут поместить в один единственный класс, объявить все методы статическими и использовать их из любого фрагмента кода. Таким образом, в каждом конкретном приложении будет своя кривая. Нужно лишь понять, к какой из этих двух категорий она ближе.
Как влияют фреймворки и инструменты разработки на кривую стоимости?
Проблема в том, что используемые средства накладывают ограничения, которые не позволят вам реализовать тот или иной подход в полной мере. Например, с помощью Dapper не удобно работать со сложными ассоциациями внутри доменных сущностей. А при использовании ORM уровня Entity Framework вы добавляете код для отображения сущностей на таблицы. Если говорить о NoSQL СУБД, для примера Neo4j, то там очень выразительный и мощный для своих задач язык. Но опять же это приведет к использованию процедурной парадигмы.
Насколько легко сменить выбранное решение?
Выводы
Из всего, что мы обсудили, можно сделать выводы:
При проектировании сервиса с нуля лучше сразу прогнозировать дальнейшее развитие этого сервиса и выбирать наиболее подходящее типовое решение.
Если дальнейшее развитие для сервиса не очевидно, то лучше сразу позаботиться о возможной смене парадигмы. Например, предпочитая eventual consistency. При добавлении нового функционала всегда держать в уме возможность смены решения.
Какие еще выводы вы могли бы предложить? Оставляйте ваши комментарии, давайте обсудим.
Бизнес-логика, что это такое?
Шаблон MVC описывает простой способ построения структуры приложения, целью которого является отделение бизнес-логики от пользовательского интерфейса. В результате, приложение легче масштабируется, тестируется, сопровождается и конечно же реализуется.
Не совсем ясно, что означает этот термин
5 ответов 5
MVC позволяет выделить «не-бизнес» логику, связанную с пользовательским интерфейсом:
тем самым оставив в модели «чистую» бизнес-логику, не привязанную к интерфейсу пользователя.
Взаимодействие в современном MVC выглядит вот так:
По бизнес-логике приюта для животных, предположим, котика, которого за неделю не забрали новые хозяева, надо усыпить. А до этого его надо кормить, поить и спать укладывать.
Если вы перепутаете бизнес-логику приюта для животных и детского приюта, и усыпите ребенка, а котенку подарите куклу, вы, надеюсь, попадете в тюрячку, там вам все за ООП расскажут.
Вы не отделили интерфейс (панель управления для запуска котят на луну) от бизнес-логики и все запуталось.
Под правильно подразумевается корректность результатов в приемлемое время. Все остальное ваших заказчиков не интересует. До тех пор, пока они не являются вашими владельцами.
P.S. Маленький исторический экскурс. Бизнес-логикой это называется потому, что в Нормальном Мире, во Внешней Империи, программирование в коммерции и корпорациях развивалось еще с 50х-60х годов: банки, страховые агентства, туроператоры, медицина.
Т.е. тебе платили за то, чтобы ты внедрил требования конкретного бизнеса
Хорошо, что это бизнес-логика, а не партийная логика, как в Северной Корее.
Python service layer: основы оформления бизнес-логики на примере Django-приложений
В этой статье я хотел бы попробовать дать стартовую точку на пути выделения слоя бизнес-логики у себя в приложениях и навести на новые мысли тех разработчиков, которые считают выделение этого слоя в своих приложениях чем-то излишним.
Так же хочу обратить внимание, что цель данной статьи не в том, чтобы дать правила, которым требуется слепо следовать, но в том, чтобы указать направление. Сервисный слой и в принципе его наличие, это такая вещь, которую нужно адаптировать под нужды вашей команды, компании и бизнеса.
Как обычно обстоят дела в реальных Django-проектах?
Большинство начинающих разработчиков на Django, после прохождения официального туториала, зачастую начинают интересоваться, собственно, а где и как им хранить код? Вариантов много, но типичный Django-разработчик, скорее всего, найдет для себя ответ в знаменитой книге «Two Scopes of Django», заключающийся в следующем принципе: «Fat Models, Utility Modules, Thin Views, Stupid Templates».
Со временем данный подход стал дефолтным в Django-сообществе. И этот подход, несомненно, работает. Какое-то время.
В реальности, большинство крупных проектов представляют из себя не просто CRUD-приложения, а нечто большее. Более менее серьезный бизнес-процесс подразумевает за собой манипулирование несколькими сущностями, какие-то промежуточные операции и прочее.
Следуя данному принципу, в какой-то момент роста проекта вырисовывается весьма интересная картина.
Эти модели слишком толстые
На самом деле, считаю правило «толстых моделей» корнем всех проблем. Самые простые бизнес-процессы, как правило, взаимодействуют только с одной сущностью. Но с ростом этих сущностей в одном бизнес-процессе у разработчика возникает следующая дилемма: «Ок, я написал огромную простыню кода, которая использует несколько моделей. В какую из моделей мне положить всё это добро?».
В худшем случае разработчик оставит весь код в модели, импортируя модели друг в друга или вынося некоторые куски кода в некие другие модули, затем снова импортируя их эти же в модели. Добро пожаловать в кольцевые импорты! В вырожденных случаях разработчик может просто начать складировать код всех моделей и их логики в один файл, получая на выходе один models.py на 1000+ строк кода.
Но чаще всего бизнес-логика начинает плавно перетекать во views.
Кажется, наши тонкие views становятся не такими уж и тонкими
Однако, реальность довольна сурова. Бизнес-логика перетекает во views бесконтрольно, потому что никто точно не может сказать, когда наша thin view стала не такой уж и thin. А писать код во views быстро и просто. Там сразу и request-объект со всеми данными, и формы, которые эти данные отвалидировали.
Впоследствии размер view начинает постепенно расти и в коде начинают появляться интересные ситуации, например, использование элемента глобального состояния view, такого как request-объект, прямо в бизнес логике, что намертво прибивает эту бизнес-логику к этой view.
Разработчикам удобно использовать глобальное состояние view прямо в бизнес-логике. Некоторые даже не брезгуют доклеивать к нему свои промежуточные вычисления. Это всегда затрудняет чтение кода. Это делает невозможным переиспользование данной бизнес-логики в других местах проекта, таких как celery-задачи, или management-команды. В конце концов это мешает вам адекватно покрыть ваш код unit-тестами. Единственной точкой тестирования в этом случае остается ваш view.
На этом этапе бизнес-логика становится сильно привязанной к инфраструктурному слою (фреймворк/библиотека) вашего проекта.
Каша из Utility Modules
В этих модулях часто могут лежать как и элементы бизнес-логики, так и какие-то универсальные утилиты. Одним словом, каша.
Сервисный слой
Основа концепции сервисного слоя закладывается в понимании разницы между бизнес-логикой и инфраструктурой. Часто разработчики склонны путать эти понятия, поэтому давайте дадим им определения.
Бизнес-логика в сервисном слое стремится быть максимально изолированной от нашей инфраструктуры, которая представляет из себя детали реализации фреймворка и других внешних зависимостей, и быть максимально близкой к предметной области. Я специально использую слово стремится вместо должна, потому что разработчики должны самостоятельно решать, какой уровень изоляции им требуется.
Если говорить в терминах Django, то целью сервисного слоя будет вынести весь код, относящийся к бизнес-логике приложения, из моделей, view и всех остальных мест, где её быть не должно, вроде middlewares или management-команд, в отдельные модули, оформленные по определенным правилам, оставляя в инфраструктурном слое лишь вызовы из этих модулей.
В рамках сервисного слоя можно выделить также инфраструктурные сервисы. Дело в том, что полностью вынести какие-то инфраструктурные операции за пределы бизнес-логики далеко не всегда возможно. Например, такие операции, как общение с СУБД, запись/чтение диска, хождение по сети. Их-то и можно изолировать в инфраструктурных сервисах, чтобы затем использовать в своей бизнес-логике c помощью более высокоуровневого интерфейса.
Инфраструктурные сервисы здорово помогают читать бизнес-логику, так как скрывают детали реализации работы с вашей инфраструктурой, а также упрощают написание тестов бизнес-логики, так как один сервисный эндпоинт гораздо проще подменить на mock, чем набор низкоуровневых операций.
Таким образом, сервисом в самом общем понимании является базовый блок кода, слоя бизнес-логики, либо инфраструктурного слоя, но не одновременно.
Сервисный слой на уровне структуры проекта
Вы также можете сделать один глобальный модуль сервисов, если у вас, например, мало django-приложений, словом, отталкивайтесь от своего проекта.
Внутри services будут храниться наши модули сервисов. Каждый отдельный модуль сервисов хранит в себе какой-то один бизнес-процесс, объединённый тесным контекстом. Модуль сервиса на уровне структуры проекта может состоять как из одного py-файла, так и из сложного набора подмодулей, организованного исходя из требований вашей бизнес-логики. Соблюдайте баланс, старайтесь не класть несколько сервисов используемых в рамках одного бизнес-процесса в один файл:
Также структуру сервисного слоя можно оформить исходя из разделения на инфраструктурные сервисы и сервисы бизнес-логики.
Сервисный слой на уровне кода
Проектируя код сервисного слоя, в голове следует держать главное правило:
В сервисном слое следует изолировать бизнес-логику от инфраструктуры.
Проектируя сервисный слой, вы должны заставить работать свой фреймворк на свою бизнес-логику, а не наоборот, как это часто происходит в Django-приложениях. Это значит, что вы не должны использовать в коде сервисов бизнес-логики такие вещи, как request-объекты, которые принимают views, формы, celery-задачи, различные сторонние библиотеки, отвечающие за инфраструктурные задачи и т. д. Это правило очень важно. И весь подход к написанию кода отталкивается именно от него. В местах, когда вынести из пайплайна бизнес-логики инфраструктуру невозможно, требуется должным образом её изолировать. Способы изоляции будут описаны далее.
На уровне кода типичный сервис бизнес-логики представляет из себя разновидность паттерна Command, который является производной от паттерна Method Object.
Для примера придумаем простой сервис с минимальным количеством бизнес-логики. Допустим, требуется периодически готовить отчёт о пользователях в системе. Нужно взять все username пользователей, затем сохранить их в csv-файл, имя которого должно быть сгенерировано определенным образом.
Создадим в директории services файл make_users_report_service.py со следующим содержимым:
Такой сервис в виде класса является базовым строительным блоком сервисного слоя. Давайте внимательно рассмотрим его особенности:
1) Используются аннотации типов
Если методы вашего сервиса возвращают или принимают инфраструктурные объекты, к примеру, из Django, то это является явным маркером того, что вы что-то делаете не так.
Аннотации типов также помогают отразить неявные зависимости внутри кода, так как вам придется импортировать типы, объекты которых не создаются в вашем коде напрямую, если вы хотите использовать их в качестве аргументов или возвращаемых значений методов.
2) В коде единственная публичная точка входа
Данный подход помогает в проектировании сервисов. Помните, если вам хочется сделать несколько публичных методов подобных execute в одном сервисе, то это явный признак того, что скорее всего логику нужно разделить и вынести в отдельный сервис.
3) Изолированы обращения к СУБД
Для себя я вывел такую формулу: если возможно, покрывайте ваш сервис на 70% юнит-тестами с замоканным источником данных и на 30% интеграционными тестами, которые умеют поднимать вашу инфраструктуру, частью которой и является ваш источник данных в виде СУБД. Такая практика сделает приятнее разработку по TDD, а также ускорит прохождение тестов в вашем CI/CD пайплайне, что тоже не может не радовать.
4) Изолированы обращения к коду формирования csv-файла
5) Название сервиса отражает конкретное действие
Название сервиса должно отражать некое конкретное действие. Размытое название сигнализирует о том, что код выполняет более чем одно конкретное действие, что является нежелательным для сервисов бизнес-логики.
Только что мы рассмотрели пример очень простого сервиса, состоящего из трёх простых этапов. Бизнес-логики в этом сервисе было весьма мало. В реальности сервисы, конечно же, гораздо сложнее. Давайте рассмотрим, какие проблемы у вас могут возникнуть с кодом выше и как их можно решить в рамках сервисного слоя.
Value Object, DTO, DAO
Давайте представим, что теперь в наш отчёт нужно писать не только username-ы пользователей, но так же и их emal-ы, имена, id и прочее. В рамках сервисного слоя мы стремимся отгородить бизнес-логику от инфраструктуры. А это значит, что вернув список из объектов Django-модели, мы отступим от наших принципов.
Тогда, часть кода выше, отвечающая за запрос к СУБД можно модифицировать следующим образом (реализацию остальных методов пока опустим):
Чаще всего, помимо чтения данных, может понадобится и много других операций с хранилищем: создание, обновление данных, агрегация. Как оставить сервис простым и не засорять бизнес-логику кодом работы с хранилищем?
Таким образом, в коде сервиса вашей бизнес-логики остаётся только использование DAO без построения запросов к СУБД напрямую.
Изолирование работы с ORM в коде обычно вызывает больше всего негативных эмоций у Django-разработчиков. Думаю, это происходит в первую очередь из-за того, что очень часто доменная модель бизнес-сущностей накладывается на модели Django в начале разработки новой фичи.
Может быть, такая изоляция и выглядит избыточной, когда в примере можно сделать всего один простой запрос в ORM, но поверьте, если для бизнес-логики вам в какой-то момент потребуется не просто достать набор строк из таблицы, а собрать некий агрегат, делая несколько запросов в разные источники данных, или сделать raw-sql запрос через драйвер к СУБД, который возвращает вместо адекватного объекта какой-то tuple из tuple-ов, то помимо всех достоинств, описанных ещё в предыдущем более простом примере, вы получите ещё и улучшенную в разы читаемость кода.
Так же весьма важным эффектом является то, что изолируя ORM, если в какой-то момет вам придётся заменить источник данных, к примеру, на MongoDB, или вообще, веб-API вашего другого сервиса, вам не придётся переписывать кучу unit-тестов и всю бизнес-логику. Нужно будет только переписать тесты на ваш DAO или метод сервиса, который возвращает DTO/Value Object. Главное лишь то, чтобы ваш код изолирующий работу с данными сохранял старый интерфейс. Сделайте вашу инфраструктуру зависимой от бизнес-логики, а не наоборот!
Чаще всего, нам требуется писать сложные пайплайны бизнес-логики, и в таких случаях, при помещении всего кода в один сервис, он становится плохо читаемым. Тогда требуется отделять сложные части пайплайна в отдельные сервисы. Таким образом, сервисы могут быть комплексными и использовать под капотом другие сервисы, как инфраструктурные, так и доменные.
Теперь давайте снова усложним наш пример. Представим, что заказчик захотел, чтобы помимо csv-файла была так же возможность сгенерировать и exel-файл.
Модифицируем исходный файл make_users_report_service.py (снова опустим подробности реализации):
И далее, создадим новый файл с инфраструктурными сервисами, реализованными в виде адаптеров report_file_adapters.py :
Таким образом, вызывать сервис бизнес-логики вы сможете с разными адаптерами, в зависимости от того, какой файл вам нужно сгенерировать.
Давайте рассмотрим написанный код подробнее:
1) Inversion of Control
С помощью абстрактного базового класса мы эмулировали интерфейс в нашем коде и положили его именно рядом с нашей бизнес-логикой, а не адаптерами. Таким образом, мы смогли достичь Инверсии управления в нашем коде. Благодаря этому в файл с бизнес-логикой не нужно делать импорты инфраструктурных сервисов, которые умеют писать csv/xlsx. Мы добились зависимости инфраструктурного слоя от бизнес-логики, а не наоборот.
Вы так же можете достичь IoC с помощью типа Protocol, появившегося в typing начиная с python 3.8.
Многие считают IoC в python излишним. Применяйте по ситуации: если вам не нужна высокая степень изоляции компонентов, можно обойтись и без IoC, либо использовать абстрактные базовые классы с реализацией, которые уже следовало бы держать рядом с адаптерами в моём примере. Сервисный слой гибок.
2) Удобный mock
О любви Python-сообщества к библиотекам и зависимости от инфрастурктуры
Я против использования подобных библиотек. И вот почему:
Сервисный слой должен оставаться гибким, и подходить потребностям вашей команды. Имейте это в виду, если всё-таки решитесь завязать ядро вашего приложения, которым является ваша бизнес-логика, на какую-то библиотеку.
Что дальше?
Лучше всех по теме негативных последствий от зависимости бизнес-логики от инфраструктуры приложения уже высказывался Роберт Мартин в своих статьях «Screaming Architecture» и «The Clean Architecture», а также прекрасной книге «Clean Architecture: A Craftsman’s Guide to Software Structure and Design».
В принципе, если возвести все приемы, которые я показал в статье, в абсолют, и везде использовать DI и IoC, а также ещё пару приёмов, то у вас получится своя реализация чистой архитектуры.
Вы могли видеть в данной статье элементы Domain-driven design. Для ознакомления рекомендую обратить внимание на книгу «Domain-Driven Design: Tackling Complexity in the Heart of Software» от Эрика Эванса. Сервисный слой можно также развить в полноценное DDD приложение.
Подводя итог
Итак, подведём итог нашему путешествию в сервисный слой:
Трафик данных в сервисах, а также между ними, лучше всего осуществлять в примитивах языках и пользовательских объектах с помощью Value Object, DTO, DAO.
Больше тестов! Покрывайте сервисы тестами, активно мокайте инфраструктуру и другие сервисы от которых вы зависите.
Сервисы могут быть комплексными и вызывать под капотом другие сервисы. Такое взаимодействие будет удобно организовать через Dependency Injection.
Сервисный слой должен подходить потребностям вашей команды. Опасайтесь завязки на чужие решения в виде библиотек или фреймворков. Используйте только те приёмы, что вы считаете нужными. Возможно, просто вынесение кода из ваших views, без серьезной изоляции инфраструктуры, может решить большинство ваших проблем.
Что такое бизнес-логика
Логика, да не совсем та
Дорогие читатели, в 100% случаев вы используете логику для того, чтобы разобраться в том, как работает продукт, который вы делаете и вам кажется, что именно это и есть UX. Основную часть того самого UX составляет бизнес-логика. Скорее всего вы спросите, почему дизайнера вообще должен волновать вопрос бизнеса. Ну логика-то ладно, а что такое бизнес-логика?
Давайте разберемся, что же такое бизнес-логика:
Бизнес-логика описывает работу всех бизнес-процессов, существующих в продукте.
Воу-воу-воу, полегче.. Это же и есть UX!
И да и нет. Под термином «Бизнес-логика» действительно понимают UX, но есть существенный нюанс.
Обычно к UX-дизайну относятся только пользовательские сценарии. Тогда как бизнес-логика описывает именно бизнес-процессы, происходящие под капотом UX с сугубо технической точки зрения.
Если бизнес-логика отвечает на вопрос:
«Как продукт должен работать технически?»
То UX-дизайн отвечает на вопрос:
«Как пользователь будет пользоваться продуктом и как сделать этот процесс максимально удобным и быстрым?».
Наглядная разница
UX-дизайн рассматривает ситуации (сценарии), с которыми сталкивается пользователь в процессе использования продукта; проблемы, которые продукт должен решить, чтобы им было интересно, выгодно или, как минимум, удобно пользоваться.
Бизнес-логика, наоборот, есть набор различных бизнес-процессов, возникающих внутри продукта. Они связаны между собой сугубо технически и никак не связаны с UX-дизайном.
UX-дизайн
То, как видит логику работы части приложения UX-дизайнер.
Бизнес-логика
То, что должен видеть хороший UX-дизайнер и продакт менеджер.
В реальной жизни бизнес-процесс устроен несколько сложнее, но общая идея и различие с UX-дизайном должны быть понятно.
Тэйк эвэй
Термин «Бизнес-логика» вы вряд ли услышите в стартапе, нацеленном на продажу смуззи, зато этот термин в широком ходу в B2B и интеграторах.
Теперь вас точно не испугаешь замысловатым вопросом «А как устроена бизнес-логика?». Помните, что бизнес-логика – это про весь механизм работы продукта, а UX-дизайном является лишь то, что по факту увидит пользователь в интерфейсе, в email и sms, отправленные вашим продуктом.
Что такое бизнес логика android приложения?
Простой 1 комментарий
Бизнес-логика, это правила того или иного бизнеса. Бизнес-модель, это модель которая описывает бизнес-процессы организации/компании/сообщества и т.п.
Например это может быть логика расчета «премии» сотрудникам. Это может быть логика например вычисления пенни за просроченный платеж. Или например в компании существуют критерии и правила по которым устанавливается лучший сотрудник месяца. А может быть у вас есть компания которая занимается логистикой и есть определенные правила по которым в компании вычисляют маршрут доставки и виды транспорта которым груз будет доставляться. Описание этих критериев и правил в программном коде и есть бизнес-логика.
Как правило бизнес-логика не меняется от приложения к приложению и не зависит от платформ и фреймворков вообще. Она меняется когда меняется сам бизнес, структура организации, взаимодействия внутри компании бизнес которой вы автоматизируете с помощью приложения.
Бизнес логика не от слова «бизнес как средство получения прибыли», а от слова бизнес как «выполняемое дело»,
«Как бы бред написали». Процитируйте, где я сказал что это логика бизнеса как средства получения прибыли? Я сказал что бизнес-логика это средство описания бизнес-процессов. Бизнес-процесс — это совокупность взаимосвязанных мероприятий или работ, направленных на создание определённого продукта или услуги для потребителей. ( Читать: https://en.wikipedia.org/wiki/Business_logic )
Вынесение б.л. в отдельные от слоя данных объекты красивая, но не всегда применимая концепция, хотя в целом хорошо укладывается в практически все принципы ООП (читать AR vs DataMapper)
`AR и DataMapper` это детали реализации инфраструктурного слоя и не более. А концепция отделения БЛ в отдельный слой применима даже за рамками контекста ООП. Хотя есть случай когда она не применима. Это когда вы пишете на PHP-шном FullStack фреймворке и женились на нем. (Читать: Мартина Фаулера)
построение связей между программными компонентами.
Бизнес-логика — это то, что программа делает с точки зрения пользователя. По-другому (и более понятно) — логика предметной отрасли.
Например, у нас есть игра в шахматы. Бизнес-логика — это правила шахмат, принципы работы часов, команды «попросить ход назад», «сдаться» и «согласиться на ничью». Если нужно начинать не с исходной позиции, а с любой — то редактор.
Крайне спорно, относить ли к бизнес-логике — анимация фигурок на манер Battle Chess и боты.
Логика, которая не бизнес — это работа с сетью, графикой, конфигурационными файлами, сохранениями досок и партий, античит и многое другое. В общем, то, что нужно для жизнеобеспечения программы, а не для предметной отрасли. Сохранять партии в PGN или XML, как перекидываться пакетами по сети и какие настройки держать для совместимости…
Предположим, вы хотите написать программу, которая будет считать коммунальные расходы.