К основному контенту

Паттерны домена: Модель предметной области

Название: Модель предметной области [ Domain Model ]

Источник:
Фаулер Мартин. Архитектура корпоративных программных приложений - Москва: издательский дом "Вильямс", 2004 г.

Аннотация:
Это объектная модель домена, охватывающая поведение (функции) и свойства (данные).

Эскиз:


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

Принцип действия:
Реализация модели предметной области означает пополнение приложения целым слоем объектов, описывающих различные стороны определённой области бизнеса. Одни объекты призваны имитировать элементы данных, которыми оперируют в этой области, а другие должны формализовать те или иные бизнес-правила. Функции тесно сочетаются с данными, которыми они манипулируют.
Объектно-ориентированная модель предметной области часто напоминает схему соответствующей базы данных, хотя между ними всё ещё остаётся множество различий. В модели предметной области смешиваются данные и функции, допускаются многозначные атрибуты, создаются сложные сети ассоциаций и используются связи наследования.
В сфере корпоративных программных приложений можно выделить две разновидности модели предметной области. «Простая» во многом походит на схему базы данных и содержит, как правило, по одному объекту домена в расчёте на каждую таблицу. "Сложная" модель может отличаться от структуры базы данных и содержать иерархии наследования, а так же сложные сети мелких взаимосвязных объектов. Сложная модель более адекватно представляет запутанную бизнес-логику, но труднее поддаётся отображению в реляционную схему базы данных. В простых моделях подчас достаточно применять варианты тривиального типового решения активная запись (Active Record) , в то время как в сложных без замысловатых преобразователей данных (Data Mapper) порой просто не обойтись.
Бизнес-логика обычно подвержена частым изменениям, поэтому весьма важна возможность простой модификации и тестирования этого слоя кода. Отсюда следует настоятельная необходимость снижать степень зависимости модели предметной области от других слоёв системы. Более того, как сможете убедиться, именно это требование является основополагающим аспектом многих типовых решений, имеющих отношение к "расслоению" системы.
С моделью предметной области связано большое количество различных контекстов. Простейший вариант – однопользовательское приложение, где единый граф объектов считывается из дискового файла и располагается в оперативной памяти. Такой стиль работы присущ настольным программам, но не менее характерен для многоуровневых приложений, поскольку в них намного больше объектов. Размещение каждого объекта в памяти сопряжено с чрезмерными затратами ресурсов памяти и времени. Прелесть объектно-ориентированных систем баз данных заключается в том, они создают впечатление, будто объекты пребывают в памяти постоянно.
Без такой системы заботится о создании объектов придётся самому. Обычно в ходе выполнения сеанса в память загружается полный граф объектов, хотя речь вовсе не идёт обо всех объектах и, может быть, классах. Если, например, ведётся поиск множества контрактов, достаточно считать информацию только о таких продуктах, которые упоминаются в этих контрактах. Если же в вычислениях участвуют объекты контрактов и зачетных доходов, объекты продуктов, возможно, создавать вовсе не нужно. Точный перечень данных, загружаемых в память, определяется параметрами объектно-реляционного отображения.
Одна из типичных проблем бизнес-логики связана с чрезмерным увеличением объектов. Занимаясь конструированием интерфейсного экрана, позволяющего манипулировать заказами, вы наверняка заметите, что только некоторые функции отличаются сугубо специфическим характером и узким назначением. Возлагая на единственный класс заказа всю полноту ответственности существует риск раздуть его до непомерной величины. Чтобы избежать подобного, можно выделить общие характеристики «заказов» и сосредоточить их в одноимённом классе, а все остальные функции вынести во вспомогательные классы сценариев транзакции (Transaction Script) или даже слоя представления.
При этом, однако, возникает опасность повторения фрагментов кода. Функции, не относящиеся к категории общих, отыскать довольно трудно, и многие предпочитают этим просто не заниматься, соглашаясь с дублированием кода. Повторение часто приводит к усложнению и несогласованности, хотя возможно эффекты излишнего увеличения размеров классов наблюдаются значительно реже, чем было ожидать.
Если такое действительно происходит, результаты вполне очевидны и легко поправимы. Поэтому советуется размещать весь родственный код в пределах одного класса и заниматься его разделением по нескольким классам только тогда, когда это в самом деле целесообразно.

Назначение:
Если вопросы как, касающиеся модели предметной области, трудны потому, что предмет чересчур велик, вопрос когда сложен ввиду неопределенности ситуации. Все зависит от степени сложности поведения системы. Если вам приходится иметь дело с изощренными и часто меняющимися бизнес-правилами, включающими проверки, вычисления и ветвления, вполне вероятно, что для их описания вы предпочтете объектную модель. Если, напротив, речь идет о паре сравнений значения с нулем и нескольких операциях сложения, проще прибегнуть к сценарию транзакции (Transaction Script).
Существует еще один фактор, который нельзя обойти вниманием: насколько комфортно чувствует себя команда разработчиков, манипулируя объектами домена. Изучение способов проектирования и применения модели предметной области – урок крайне сложный, пробудивший к жизни целый информационный пласт о «смене парадигмы». Чтобы привыкнуть к модели, нужны практика и советы профессионала, но зато среди тех, кто дошел до цели, мне почти не встречались такие, кто хотел бы вновь вернуться к сценарию транзакции разве только в самых простых случаях.
При необходимости взаимодействия с базой данных в контексте модели предметной области, прежде всего я обратился бы к преобразователю данных. Это типовое решение поможет сохранить независимость бизнес-модели от схемы базы данных и обеспечить наилучшие возможности изменения их в будущем.
Встречаются ситуации, когда модель предметной области целесообразно снабдить более отчетливым интерфейсом API, и для этого можно порекомендовать типовое решение слой служб (Service Layer).


Комментарии

Популярные сообщения из этого блога

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

Что такое бизнес-логика в программировании? При проектировании и реализации программных систем часто сталкиваешься с такими понятиями как: Бизнес-логика; Бизнес-правила; Бизнес-ограничение; Бизнес-операция; и т.д. Так что же это такое? Все эти термины начинаются со слова «бизнес», которое обычно и вводят начинающих программистов в заблуждение. Пытаясь найти определение в интернете, программисты натыкаются примерно на следующее: Б изнес (англ. business — «дело», «предприятие») — деятельность, направленная на получение прибыли; любой вид деятельности, приносящий доход или иные личные выгоды ( wiki ).   Данное определение не применимо в рамках реализации программного продукта, и не связано с какой-либо коммерческой деятельностью.  Термин Бизнес можно заменить на понятие Предметная Область(ПО), от которого и надо отталкиваться. Предметная область ( domain ) – это часть реального мира занимающееся деятельностью, которая служит объектом автоматизации (не путайте данное опр...

Какая-то вторя статься о чем-то...

Свойство выравнивает flex-элементы по главной оси flex-контейнера, распределяя свободное пространство, незанятое flex-элементами. Когда элемент преобразуется в flex-контейнер, flex-элементы по умолчанию сгруппированы вместе (если для них не заданы поля  margin ). Промежутки добавляются после расчета значений  margin  и  flex-grow . Если какие-либо элементы имеют ненулевое значение  flex-grow  или  margin: auto; , свойство не будет оказывать влияния. Свойство не наследуется.