что такое бизнес логика в программировании

Бизнес-логика, что это такое?

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

Не совсем ясно, что означает этот термин

5 ответов 5

MVC позволяет выделить «не-бизнес» логику, связанную с пользовательским интерфейсом:

тем самым оставив в модели «чистую» бизнес-логику, не привязанную к интерфейсу пользователя.

Взаимодействие в современном MVC выглядит вот так:

По бизнес-логике приюта для животных, предположим, котика, которого за неделю не забрали новые хозяева, надо усыпить. А до этого его надо кормить, поить и спать укладывать.

Если вы перепутаете бизнес-логику приюта для животных и детского приюта, и усыпите ребенка, а котенку подарите куклу, вы, надеюсь, попадете в тюрячку, там вам все за ООП расскажут.

Вы не отделили интерфейс (панель управления для запуска котят на луну) от бизнес-логики и все запуталось.

Под правильно подразумевается корректность результатов в приемлемое время. Все остальное ваших заказчиков не интересует. До тех пор, пока они не являются вашими владельцами.

P.S. Маленький исторический экскурс. Бизнес-логикой это называется потому, что в Нормальном Мире, во Внешней Империи, программирование в коммерции и корпорациях развивалось еще с 50х-60х годов: банки, страховые агентства, туроператоры, медицина.

Т.е. тебе платили за то, чтобы ты внедрил требования конкретного бизнеса

Хорошо, что это бизнес-логика, а не партийная логика, как в Северной Корее.

Источник

Решение проблем организации бизнес-логики в PHP или как пойти своим путем

Привет, Хабр! Не первый раз я пытаюсь написать эту статью, но давно уже есть желание поделиться опытом и люди просят.

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

Статья будет о том как мы организовали работу с бизнес логикой в PHP, совмещающую разные подходы.

Тут будет изложено как уйти от проблем PHP фреймворков, связанных с размазыванием предметной логики по слою контроллеров.

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

Немного о том как работать с бизнес логикой в популярных PHP фреймворках

Обычная ситуация

Если мы смотрим на самые популярные фреймворки то за основу в них взят архитектурный паттерн MVC. Инструментов по организации бизнес логики как таковых нет, а вот для создания простых crud все есть.

Стандартная ситуация которую мы видим в большинстве случаев это анемичная модель, когда например класс UserModel является просто набором атрибутов и не содержит никакой логики. Бизнес логика же содержится в слое контроллеров.

Контроллеры превращаются в что-то среднее между Transaction Script и Service Layer в Domain Model. Они валидируют входные данные, получают из базы модельные сущности и реализуют бизнес логику этих сущностей.

Я не говорю, что это неправильно, в некоторых случаях это оправдывающий себя подход. Когда стоит разрабатывать без какой-то сложной архитектуры для бизнес логики:

Сложная бизнес логика

Если бизнес логика достаточно сложна то есть два стандартных варианта решения:

Transaction Script

Чтобы отделить бизнес логику от фреймворка стоит выделать ее в отдельные сущности. Используя Transaction Script мы можем создать большой набор сценариев, обрабатывающих конкретные запросы пользователей.

Например если нужно загрузить фото то можно создать сценарий загрузки фото. Программно он может быть выделен в отдельный класс:

Подробнее советую почитать об этом подходе в книге «Архитектура корпоративных программных приложений», там описаны все его плюсы и минусы.

Domain Model

При реализации Domain Model все становится значительно сложнее. Надо продумать бизнес логику и выделить сущности с четко разделенной ответственностью. Тут много подводных камней, это и как организовать фасад для предметной области и как избежать создания приложения с клубком связей между бизнес сущностями и т.д.

В книге «Архитектура корпоративных программных приложений» предлагается ввести слой Service Layer который послужит интерфейсом бизнес логики и будет состоять из нескольких сервисов сгруппированных по общему функционалу(например UserService, OrderService и т.д.).

Более подробной этот подход рассмотрен в книгах «Архитектура корпоративных программных приложений» и также ему посвящена целая книга «Предметно-ориентированное проектирование (DDD)», которую я лично очень рекомендую к прочтению.

Наша история

Как все начиналось

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

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

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

Архитектура, словарь

За основу была взята многослойная архитектура. Если рассматривать очень общую и укрупненную схемы то можно выделть 3 слоя:

Что-то бралось из “Большой синей книги” по DDD, что-то из книги «Архитектура корпоративных программных приложений» и все это перерабатывались, если это было необходимо, под наши нужды.

Interface

Interface это в нашем случае слой отвечающий за доступ к предметной области из внешнего мира.
У нас на данный момент есть 2 вида интерфейса:

API — это RESTful api состоящий из View и Controller.

CLI — интерфейс вызова бизнес логики из командной строки(например крон задачи, воркеры для очередей, и т.д.).

Данная часть слоя Interface очень проста, так как наши проекты на PHP это исключительно API и не имеют пользовательского интерфейса.

Соответственно не было необходимости включать работу с шаблонизаторами, мы просто отдаем view в виде json.

При необходимости этот функционал можно расширить, добавить поддержку шаблонизаторов, ввести разные форматы отдачи ответа (например xml ), но у нас таких потребностей пока нет. Данное упрощение позволило больше времени уделять более важным частям архитектуры.

Controller

Контроллеры не должны содержать никакой логики предметной области. Контроллер просто получает запрос от роутера и вызывает соответствующий интерфейс модели с параметрами запроса. Он может делать какое-то небольшое преобразование для связи с моделью но никакой бизнес логики в нем нет.

Model

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

Было выделено 3 основных обобщенных элемента модели:

Entity — это сущность с набором характеристик в виде списка параметров и с поведением в виде функций.
Context — это сценарий в рамках которого взаимодействуют сущности.
Repository — это абстракция для хранения Entity.

Storage

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

Подробно теория

View-Controller

Эта часть платформы организует API интерфейс для бизнес логики из вне. Она состоит из множества элементов, но для понимания можно описать несколько:

Router — маршрутизатор http запросов в соответствующий метод контроллера (все стандартно).

View — это по сути преобразователь ответов от модели передаваемых как ValueObjet ( тут мы тоже, не даем view много знаний о бизнес логики) в json. Хотя в классическом MVC view получает обновления от model напрямую, у нас это делается через Controller.

Controller это прослойка скрывающая интерфейсы модели. Controller преобразует http запрос в входные параметры для модели, вызывает сценарий модели, получает результат выполнения и возвращает его View для отображения.

Это часть не содержит никакой бизнес логики и в течении проекта не меняется если только не нужно создать новые API интерфейсы. Мы не раздуваем слой контроллеров, оставляем их компактными и простыми.

Модель

А теперь поговорим о самом главном и ценном элементе, заключающем в себя бизнес логику.
Рассмотрим подробнее основные элементы модели: Entity, Context и Repository.

Entity это сущности предметной области, например пользователь, заказ, автомобиль и т.д. Все подобные сущности могут иметь параметры: идентификатор, время регистрации, цена, скорость. Работу с параметрами мы обеспечиваем в базовом классе Entity, а поведение уже определяет разработчик в классах наследниках.

Список параметров так же нужен для сохранения Entity в базу данных, но модель ничего об этом сохранении не знает. В инфраструктурном уровне есть мапперы которые знают как сохранять сущности модели в базу.

Идентификатор у Entity в нашей платформе это базовый параметр, он позволяет однозначно идентифицировать разные сущности внутри одно класса объектов.

Подробнее можно сказать что наш Entity очень похож на Entity, который описан в книге Эрика Эванса.

Как говорится у Эванса, идентификация объекта а программных системах это одна из важнейших задач. Так же Эванс уточняет что идентификация достигается не только за счет одних атрибутов объектов.

Что же можно считать характеристиками которые могут идентифицировать объект в программной системе: атрибуты, класс объекта, поведение. При разработке нашего Entity мы как раз отталкивались от этих характеристик.

Атрибуты могут быть разные в зависимости от сущности, но идентификатор мы выделили в базой как присущий практически всем. Класс объекта мы задаем благодаря ООП и наследованию предоставляемому нам языком разработки. Поведение задается методами для каждого класса.

Context это сценарий в рамках которого взаимодействуют Entity. Например «Регистрация пользователя» у нас отдельный контекст, и работа этого контекста выглядит примерно так:

Например набор контекстов связанных с пользователем (UserRegContext, UserGetContext, UserChangePasswordContext, и т.д.) при не аннемичном пользователе практически равноценен UserService (Service Layer). У нас есть контексты которые берут на себя очень много бизнес логики и их можно считать Transaction Script, но есть и контексты которые просто вызывают какой-то функционал Entity а дальше уже вся бизнес логика скрыта от контекста и тут они уже ближе к Service Layer.

Отсюда в случаях со сложной бизнес логикой можно либо в чистом виде сделать DDD архитектуру системы, либо можно организовать логику через Transaction Script если бизнес логика не так сложна и состоит из стандартных сценариев создать, запросить, обновить и т.д.

Репозитории это абстракиция бизнес логики для организация сохранения/удаления/обновления/поиска сущностей в базе. Конкретные репозитории работают с конкретными сущностями, например UserRepository работает с User.

Хранение данных

Хранение данных сделано с использованием мапперов. Есть обобщенный класс Mapper который содержит базовый функционал для работы с Entity.

abstract public function insert( \foci\model\Entity &$entity);
abstract public function update( \foci\model\Entity &$entity);
abstract public function delete( \foci\model\Entity &$entity);

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

Таким образом если у нас в модели есть класс User то ему в соответствие создается класс UserMapper. Логика работы с БД вынесена в отдельны слой и может быть легко заменена при необходимости.

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

Обобщенная схема

Тут расписана очень общая структура классов нашей платформы, многие мелкие менее важные классы опущены.

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

Config и PropertyList на схеме это утилитарные сущности которые используются всеми.

Немного практики (совсем чуть чуть)

Теория это хорошо, но давайте рассмотрим, как все это применить на практике. Допустим у нас есть задача сделать приложение для персонального учета финансов. Примерный словарь терминов (расписывать определения не буду, тут пока все просто): Деньги, Бюджет, Пользователь, Товар, Услуга, Календарь

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

Выделим сущности: Money, Budget, User, Product, Service, Calendar.
Выделим 3 контекста по пользовательским сценариям:

Первый контекст это просто покупка товара.

BuyOrderContex

SetSchedulePayForServiceContext

SchedulePayForServiceContext

Заключение

Наши практики

Разделение функционала

Разбиение всего приложения на контексты позволяет легко разносить его на разные сервера.
Например у нас есть контексты связанные с регистрацией пользователей, легко можно взять всю эту группу и перенести на другой сервер не нарушая работы остальных частей приложения.

Контекст вызывает контекст

Контекст может вызывать контекст, и так можно выстраивать сложные цепочки. Такой прием используется очень редко. Так же такой подход кроет в себе много подводных камней поэтому у есть планы запретить такое использование.

Крон задачи

Контекст как единица выполнения позволяет вызывать его откуда угодно. На этом основана логика запуска контекстов как крон задач.

Один из наших проектов это сайт в котором клиентская часть полностью написана на JavaScript и через RESTfull api взаимодействует с серверной часть на PHP. Мы такое даже не планировали когда начинали разработку, но эта возможность строить SPA приложения с нашей платформой в качестве сервера оказалась очень удобной.

Тестирование

Весь код покрывается тестами. Мы используем 2 вида тестов:

Планы

Что мы получили в итоге

Выводы

В общем результатом проделанной работы мы довольны. Написанная платформа решает наши задачи. Она позволяет гибко реализовывать бизнес логику, что значительно упрощает разработку. Есть множество планов по улучшению и расширению.

PS: Если такой подход к решению проблемы с предметной областью в PHP фреймворках будет интересен сообществу то мы вполне можем поднатужиться и подготовить open source.

PSS: Сразу предвижу фразы на счет того зачем вам велосипед, если все уже есть. Не вижу смысла спорить по этому поводу, это наш подход и он сработал.

PSS: Так же предвижу вопросы, зачем делать кровосмешение Transaction Script и Domain Model, а почему бы не сделать и не получить гибкий инструмент для решения бизнес задач.

Источник

Организация бизнес-логики корпоративных приложений. Какие возможны варианты?

В этой статье мы попытаемся найти ответ на вопрос, обозначений в заголовке. А также порассуждаем на тему возможности универсального решения на все случае жизни.

Три типовых решения при работе с бизнес-логикой по Фаулеру

Сколько типовых решений на самом деле?

Понятно, что речь не идет о чистой реализации той или иной парадигмы. Всегда есть компромиссы, вызванные ограничениями используемых технологий. Если вы пишете на C# или Java, объектно-ориентированных языках по своей природе, то это совсем не значит, что ваш код автоматически становится объектно-ориентированным. Всю программу вполне могут поместить в один единственный класс, объявить все методы статическими и использовать их из любого фрагмента кода. Таким образом, в каждом конкретном приложении будет своя кривая. Нужно лишь понять, к какой из этих двух категорий она ближе.

Как влияют фреймворки и инструменты разработки на кривую стоимости?

Проблема в том, что используемые средства накладывают ограничения, которые не позволят вам реализовать тот или иной подход в полной мере. Например, с помощью Dapper не удобно работать со сложными ассоциациями внутри доменных сущностей. А при использовании ORM уровня Entity Framework вы добавляете код для отображения сущностей на таблицы. Если говорить о NoSQL СУБД, для примера Neo4j, то там очень выразительный и мощный для своих задач язык. Но опять же это приведет к использованию процедурной парадигмы.

Насколько легко сменить выбранное решение?

Выводы

Из всего, что мы обсудили, можно сделать выводы:

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

Если дальнейшее развитие для сервиса не очевидно, то лучше сразу позаботиться о возможной смене парадигмы. Например, предпочитая eventual consistency. При добавлении нового функционала всегда держать в уме возможность смены решения.

Какие еще выводы вы могли бы предложить? Оставляйте ваши комментарии, давайте обсудим.

Источник

Почему мы пишем бизнес-логику на Lua

Привет, Хабр. В этом посте мы хотим рассказать о том, как и почему мы в IPONWEB используем язык программирования с красивым названием Lua.

Lua — скриптовый встраиваемый язык программирования со свободно распространяемым интерпретатором и открытыми исходными текстами на C. Он был разработан в 1993 году в Бразилии, в подразделении Tecgraf Католического университета Рио-де-Жанейро, а его прародителями были DEL (Data-Entry Language) и SOL (Simple Object Language), разработанные там же ранее. Один из прародителей, язык SOL, косвенно поучаствовал и в «крещении» новорожденного — «Sol» переводится с португальского как «солнце», а новый язык получил имя «Lua», «луна».

Легкость встраивания Lua в написанные на “системных” языках движки сделала его популярным скриптовым языком видеоигр. На Lua написаны, к примеру, скрипты в Grim Fandango и Baldur’s Gate. Те, кто играет в World of Warcraft, тоже наверняка слышали о Lua не раз и не два — именно на нем пишут аддоны к игре, облегчающие жизнь хардкорщикам, казуалам, любителям помериться эффективностью и прочим обитателям игрового мира. Вне геймдева Lua используется как скриптовый язык встроенных систем (телевизоров, принтеров, автомобильных панелей), а также приложений, например, медиаплеера VLC Media Player. Lua используют в качестве встроенного языка такие инструменты, как Tarantool, Redis и OpenResty. А еще Lua был использован как язык расширения для расчетных кодов на языке Фортран, моделирующих термомеханическое поведение ядерного топлива.

Почему Lua?

IPONWEB — разработчик высоконагруженных платформ для компаний, работающих в сфере онлайн-рекламы: DSP, SSP, рекламных агентств и рекламодателей. О нашей работе мы подробно рассказывали в этой статье. Сначала мы разрабатывали бизнес-логику наших платформ на C++, но быстро поняли, что это не лучший выбор. Для минимизации издержек важно быстродействие платформы, а также скорость разработки, и разработка на C++ оказалась для нас слишком медленной, сказалась и сложность добавления функциональности. Мы решили изолировать интерпретацию бизнес-логики от низкоуровневого серверного кода, стали искать подходящий для этого язык и остановились на Lua. Это было в 2008 году, подходящих нам реализаций JavaScript еще не существовало, Perl, Python и Ruby были слишком медленными и недостаточно легко встраивались. И был язык Lua, не слишком известный, но популярный в геймдеве, а то, чего хотели мы, оказалось схоже с потребностями разработчиков игр — нам нужен был быстрый движок для низкоуровневых операций и легко встраиваемый быстрый язык для бизнес-логики.

Lua действительно очень быстрый язык. Дополнительный прирост скорости может дать использование LuaJIT, среды исполнения для Lua 5.1, включающей в себя трассирующий JIT-компилятор (мы используем собственный форк, о котором уже писали). Поскольку мы пишем бизнес-логику для RTB-систем, скорость для нас критически важна: в RTB на обработку каждого входящего запроса есть в среднем 120 миллисекунд. При этом на исполнение кода отводится всего 10-15 миллисекунд, а остальное время занимает ожидание ответа от других сервисов. Если, например, задержку в полсекунды при загрузке сайта в сети пользователь даже не заметит, то для RTB эти 500 миллисекунд — огромный отрезок времени. Ответ на вопрос, насколько быстр язык Lua, таков: он достаточно быстр для того, чтобы мы могли много лет писать на нем бизнес-логику и оставаться в RTB-бизнесе. Будь выбранный нами язык недостаточно быстрым, писать платформу нам было бы не для кого. Означает ли это, что RTB нельзя писать на других языках? Не означает. Но мы пишем RTB на Lua и успешно справляемся со своими и клиентскими бизнес-задачами. Наглядным примером быстродействия Lua на сервере может служить и этот бенчмарк OpenResty.

Lua как встраиваемый язык имеет массу преимуществ: он минималистичный, компактный, с очень маленькой стандартной библиотекой. Его функциональность полностью дублируется на C, что обеспечивает легкое и «бесшовное» взаимодействие Lua и C. У Lua довольно низкий порог входа по сравнению со многими другими языками: большинство программистов, приходящих работать в IPONWEB, никогда раньше не писали на Lua, но им хватает нескольких дней, чтобы полноценно включиться в работу.

Вот простой пример таргетирования рекламной аудитории.

А так выглядит несложный хендлер (обработчик событий).

Простота Lua не только обеспечивает быструю разработку, но и позволяет делать большую работу малыми силами. Платформа IPONWEB — это общее решение, подстраиваемое под нужды того или иного клиента, при этом проект могут вести один разработчик и один менеджер. Читать код на Lua могут не только сами разработчики, но и менеджеры проектов, а иногда и клиенты. Вместе мы быстрее обнаруживаем проблему, находим ее причину и решение. Зачастую менеджер проекта сообщает разработчику о проблеме и тут же подсказывает путь ее решения.

При этом простота Lua может быть обманчивой, а у минимализма и компактности есть обратная сторона. Если код пишется, например, на Perl или Python, в распоряжении разработчика есть огромные хранилища готовых модулей, у Ruby есть RubyGems, богатыми хранилищами располагают и многие другие языки. А у Lua есть LuaRocks и три тысячи модулей, которые там лежат. Кроме того, даже если на LuaRocks есть нужный модуль, велика вероятность того, что придется еще поработать, чтобы им можно было пользоваться в условиях той или иной компании. Lua дает хорошие средства для создания защищенной среды исполнения кода (песочниц), а при работе в песочницах некоторые функции могут быть отключены. Это означает, что модули LuaRocks могут оказаться нерабочими в случае использования ими функций, заблокированных безопасной средой компании. Такова цена компактности и встраиваемости, но эту цену стоит заплатить — языки “с батарейками”, такие, как, например, Python, встраиваются не в пример сложнее, чем Lua.

Как это работает?

Основа нашей платформы — кастомизируемый HTTP-сервер с удобным и расширяемым API, предоставляющий Lua-разработчику набор функций и заточенный под задачи рекламного рынка. Этот сервер обрабатывает сотни миллионов запросов и пишет терабайты логов в день. Входящие запросы равномерно распределяются по системным тредам, а внутри системных тредов находятся песочницы.

Когда на сервер приходит запрос, внутри песочницы, в которую этот запрос попал, создается корутина, которая осуществляет обработку запроса. Корутины работают независимо друг от друга, каждая создающаяся корутина ставится в очередь на исполнение. Время жизни каждой корутины (полное время обработки запроса с учетом ожидания ответа вовлеченных служб: базы данных, метрик, бюджетного сервера) не должно превышать 120 миллисекунд.

Вкратце процесс обработки запроса можно описать так:

Что дальше?

А дальше, возможно, применение Lua в IPONWEB будет расширено. У нас есть идеи о том, как еще можно использовать Lua в нашем бизнесе, и когда эти идеи будут воплощены в жизнь, мы обязательно поделимся новым опытом. Удобство и возможности Lua как встраиваемого скриптового языка могут помочь нам, в частности, ускорить обработку клиентских данных. Но это пока из области планов и перспектив.

Подводя итог, можно сказать, что наш выбор языка бизнес-логики, сделанный 11 лет назад, продолжает оправдывать себя, позволяя нам успешно справляться с собственными бизнес-задачами и помогать нам в решении задач наших клиентов. Легко читаемый, легко встраиваемый, быстрый и несложный в освоении, Lua был и остается одним из лучших скриптовых языков, сфера применения которого отнюдь не ограничивается разработкой игр. Написанная на нем бизнес-логика IPONWEB — только один из подтверждающих это примеров.

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • что такое библиотеки для программирования
  • Что такое библиотеки в windows 7
  • Что такое библиотека в программировании
  • что такое библиотека в программировании простыми словами
  • Что такое библиотека в программировании python

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии