Pull to refresh

Методика проектирования архитектурных слоев на основе анемичной модели и DDD

Reading time11 min
Views12K
В результате выполнения методики будут выделены архитектурные слои с максимальной специализацией по уровням прикладных задач и разделением ответственности по SRP.

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

Как следствие, это выражается:

  • в непредсказуемости сроков разработки
  • большим временем локализации ошибок
  • увеличением требования к квалификации разработчиков и сложной заменяемости

Но как выйти на другой уровень качества приложения и разработки?

Если сравнивать архитектуру систем с архитектурой зданий, то на определённом этапе, переполненную хрущёвку надо превратить в небоскрёб. Методика описывает то, КАК это сделать.

image

Факторы-признаки-критерии качественной корпоративной системы:
— документированность и документируемость
наличие минимум пользовательской документации с описанием всего функционала
наличие как максимум панорамной документации
— стабильность
определённость во времени локализации ошибок
известность факторов возникновения ошибок
предсказуемость во времени исправления ошибок
— поддерживаемость
заменяемость разработчиков проекта — время интеграции 1-3 месяца
— расширяемость

SRP
Принцип единственной ответственности (Single Responsibility Principle, SRP) — принцип ООП, обозначающий, что каждый объект должен иметь одну ответственность (назначение). Выполнение принципа приводит к более лучшей специализации классов.

Почему может происходить несоблюдение принципа:

  • появление новой специфической функциональности, непредусмотренной изначально;
  • накопление технического долга и длительное отсутствие рефакторинга;
  • недостаточная информированность и представление разработчиками о том где и какие ресурсы приложение находятся => приводит к дублированию;
  • слияние нескольких приложений в одно;

Виды SRP

  • горизонтальное — разделение ответственности между объектами/классами одного слоя
  • вертикальное — разделение ответственности между слоями
  • инфраструктурное — разделение ответственности между системами ИТ-ландшафта

Последствия несоблюдения (примеры):

  • дублируется код;
  • усложняется и запутывается логика приложения;
  • увеличивается связанность, система становится монолитной
  • нарушается модульность
  • одна система вбирает в себя функциональность другой системы


DDD
Предметно-ориентированное проектирование (Domain-driven design, DDD) — это набор принципов и схем, направленных на создание оптимальных систем объектов. Сводится к созданию абстракций, которые называются моделями предметных областей. В эти модели входит бизнес-логика, устанавливающая связь между реальными условиями области применения продукта и кодом.

Основные составляющие DDD


— Единый язык (UBIQUITOUS LANGUAGE) — это коллективный язык терминов. Он совместно используется экспертами в предметной области и разработчиками. Фактически на нем говорят все участники команды, разрабатывающей проект. Ваша роль в команде не имеет значения. Раз вы — член команды, значит, используете для описания проекта ЕДИНЫЙ ЯЗЫК

— ЕДИНЫЙ ЯЗЫК в основном выражает то, как сам бизнес мыслит и действует.

Поскольку эксперты и разработчики совместно работают над моделью предметной области, они должны достичь консенсуса и выработать компромиссное реu.iение о наилучшем ЕДИНОМ ЯЗЫКЕ проекта. Качество ЕДИНОГО ЯЗЫКА не должно быть предметом компромисса, в него должны быть включены только самые точные понятия, термины и значения.

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

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

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

— Общая ПРЕДМЕТНАЯ ОБЛАСТЬ организации состоит из ПОДОБЛАСТЕЙ. Подход DDD позволяет разрабатывать модели в ОГРАНИЧЕННЫХ КОНТЕКСТАХ. Фактически при разработке МОДЕЛИ ПРЕДМЕТНОЙ ОБЛАСТИ мы сосредоточиваемся только на одной определенной области всей предметной области.

— ОГРАНИЧЕННЫЙ КОНТЕКСТ (BOUNDED CONTEXT) позволяет команде очертить границы, в рамках которых вырабатывается решение конкретной задачи предметной области. В рамках отдельного ОГРАНИЧЕННОГО КОНТЕКСТА команда формулирует ЕДИНЫЙ ЯЗЫК. На нем говорят члены команды и формулируется модель программного обеспечения. Разношерстные команды, отвечающие за свои ОГРАНИЧЕННЫЕ КОНТЕКСТЫ, используют КАРТУ КОНТЕКСТОВ для стратегического

Инструкция


1. Сбор, структурирование, визуализирование и анализ информации о системе


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

Параллельно с таким исследованием можно формировать скелет новой единой документации, о методике разработке которой я ещё расскажу в другой статье.

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

Для анализа полезны любые источники — jira, документация, которая может быть в виде множества разросненных документов. Как правило редко в каком проекте есть исчерпывающая структурированная документация по всей системе и её фичам, поэтому основным и универсальным инструментом для исследования функционала будут:

  1. тестовая среда;
  2. хитроумные разнообразные тест-кейсы;
  3. общение с бизнес-пользователями и заказчиками;
  4. дотошные и коварные вопросы относительно функционала.

Предприимчивость и находчивость в этой части поможет собрать наибольший объём информации в кротчайшие сроки.

Следующий момент — это визуализация. Сейчас редко увидишь разработчиков, которые часто что-то рисовали, проектировали на бумаге, но в таком рисовании есть практический смысл, так как на этом строится визуализация, которая помогает разложить всё по полочкам, смоделировать и абстрагироваться. Записывать текстом можно, но его может оказаться очень много, а грамотно изображённая абстрактная схема позволяет без длительного чтения документации сразу понять что к чему и где. Только универсальных методик в части рисования не ждите. Я много искал, но возможно вам повезло больше и вы поделитесь в комментариях. А мне пришлось придумать что-то своё.

Таким образом подводя резюме первому шагу:

  • настройтесь на сплошное изучение всей функциональности. Изучение позволит построить абстрактную модель в голове;
  • развивайте фанатизм и любовь к предметной области. Фанатизм даст энергию и идеи для хитроумного подробного анализа логики и эмоции для запоминания;
  • рисуйте на бумаге и в редакторах, схемы позволят разложить всё по полочкам.

2. Визуализация и моделирование бизнес-логики. Выделение деталей приложения (или выделение сущностей бизнес-логики)


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

Мой проект относился к электронному юридически значимому документообороту между юридическими лицами через оператора.

Инструкция и рекомендации по построению схемы объектов бизнес-логики:

2.1. Выписать все объекты, над которыми в алгоритмах производятся операции. Не стесняемся использовать те имена, которые удобны — русские, английские…


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


* можно использовать разные языки (английский/русский) в одной схеме, так как они проще воспринимаются, но не стоит стесняться смешивать языки — всё ради удобства. На этапе моделирования это не так важно, так как на этапе реализации данные поля и названия в большей части будут переведены на английский и это ничему не навредит
** скорее всего будут такие алгоритмы, в которых не используются объекты, а используются и обрабатываются только значения каких-то отдельных полей, это ожидаемо от любителей фукнционального программирования. Стоит учитывать такие ситуации и при моделировании всё же группировать такие поля в объекты, к которым они относятся, запоминать такие функциональные алгоритмы и на будущее продумывать их таким образом, чтобы они использовали объекты, а не отдельные переменные с значением поля какого-либо объекта.

image

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


Выполнение этого шага влияет на степень примерения SRP.

2.4. Выделите все действия, которые выполняются над соответствующими объектами


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

После этого шага, первая картинка расширилась ещё и новыми сущностями.

image

2.5 Выделите классы-менеджеры (сервисы)


Класс-менеджер (сервис) — это такой класс, который выполняет действия над структурами данных, при этом сам он не используется в качестве структуры данных. Это может быть обёртка над каким-то источником данных — базой данных, облаком, api, файловой системой.

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

Ландшафт нарисован в упрощённом варианте, выделены все связанные системы. Таким образом получились:

  • операторы ЭДО
  • файловая система
  • база данных
  • бизнес-логика самого приложения, в которую входят ранее выделенные сущности

image

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

  • бОльшую архитектурную гибкость;
  • уменьшение времени на доработку слоя БЛ;
  • ускорение локализации дальнейших ошибок

На рисунке отмечена связь такой сущности как ПакетДокументов с определённой структурой файлов и папок, чтобы создать представление о некоторых нюансах и технических особенностях некоторых структур. До выделения сущности ПакетДокументов в бизнес-логику, работа происходила с обычным набором документов, но так как на уровне бизнес-модели такое понятие как ПакетДокументов существовало, то приходилось учитывать низкоуровневые особенности на слое бизнес-логики.

  • взаимодействие между ERP разных компаний происходило на уровне пакетов
  • по пакетам документов приходилось формировать отдельные статусы
  • на уровне файловой системы формат пакетов отличался от формата других файлов

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

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

В упрощённом виде появилась подобная схема

image

В результате этого шага:

  1. выделены все сущности, которые содержат все необходимые данные, используемые во всех алгоритмах;
  2. выделены все действия, которые можно выполнять над сущностями. Выделенные действия распределены на соответствующие классы-менеджеры;
  3. выделены классы-менеджеры, которые выполняют активные действия над сущностями и являются обёртками над соответствующими связанными контекстами. Менеджеры совместимы друг с другом через сущности и инкапсулируют в себе логику взаимодействия со связанными системами. Это позволяет локализовать ошибки, тянущиеся из связанных систем.

CloudManager — используется для выполнения всех операций, с использованием облака операторов ЭДО и инкапсулирует всю логику взаимодействия с их API.

FSManager — используется при работе с файловой системой: особенности работы с различными форматами документов, структурой их хранения, абстракция от технических деталей реализации находится здесь, таким образом вызывая один метод SaveTo из слоя бизнес-логики, не надо задумываться об особенностях структур xml, папок, архивов, наборов фалов. Всё учтено в более низком слое. Так же в связи с тем, что существует бесчисленное количество форматов выгрузки xml, этот слой может расширяться поддержкой соответствующих форматов через дополнительные dll.

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

3. Выделение архитектурных слоёв


Под архитектурным слоем подразумевается определённый набор логики, то есть деталей приложения, которые позволяют реализовать пространство прикладных задач заданного уровня. Подробно это понятие разбирается в статье habr.com/ru/post/511252

Все прикладные задачи, реализуемые в приложении, можно разделить на уровни. Например сохранение настроек приложения лежит на более высоком уровне чем сохранение данных в файл. Выполнение действия подписания документа лежит на более высоком уровне, чем генерация ЭЦП. На разных уровнях используются свои структуры данных и менеджеры и подобное разделение может упростить работу разработчика. Допустим на ранее выделенном уровне бизнес-логики, описанной на шаге 2 — вообще нет непосредвенного обращения к крипто-провайдерам, всё было инкапсулирвоно в соответствующие классы, в которых используется своя более низкоупровневая логика.

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

1. DocumentSDK — слой работы с документами

Содержит в себе вышеописанный набор бизнес-логики, на базе которой строится работа вышесоящих слоёв

2. DocumentAutomatizationSDK — слой автоматизации работы с документами.

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

  • различные алгоритмы последовательности подписания документов,
  • информирования, коррекции, обмен статусами между ERP и учётными системами
  • выгрузки/загрузки документов в файлы и из файлов
  • настройки работы роботов

Бизнес-логика слоя включала всего 2 класса:

  • AutomatizationSettings — структура данных настроек робота
  • AutomatizationWorker — активный класс, представляющий собой многопоточного робота, выполняющего алгоритмы в соответствии с настройками

3. DocumentAutomatizationService — слой сервиса

Это Windows-служба, которая

  • предоставляет SOAP-API-интерфейс для оперативного управления работой роботов (запуск, мониторинг, изменение настроек);
  • создаёт в себе среду исполнения множества роботов.

Бизнес-логика слоя включала в себя 1 класс, предоставляющий одновременно SOAP-API и инкапсулирующий в себе коллекцию роботов предыдущего слоя.

4. DocumentAutomatizationUI — слой пользовательского интерфейса управления службой

Это Winforms приложение, которая предоставляла возмоность редактирования пользовательских настроек робота, и управление роботами через WCF, подсоединяясь локально или к удалённому серверу, на котором была развернута служба.

Такое разделение по слоям, позволило дорабатывать разные слои независимо друг от друга и улучшило разделение кода на вертикальном уровне, тем самым увеличив применение принципа SRP.

В результате методики, на примере были получены архитектурные слои и их составляющие. По детальному описанию эти архитектурные слои можно реализовать на любом объекто-ориентированном языке, в определённые сроки, используя все преимущества многослойной архитектуры для разработки, например декомпозиция задач по уровню и распараллеливание разработки слоёв, параллельной разработке UI, слоя сервиса и логики.
Tags:
Hubs:
Total votes 5: ↑3 and ↓2+1
Comments16

Articles