Поваренная книга Ruby-разработчика: Domain Driven Design рецепты ( 1-я часть, область применения )

    Введение


    Я хотел бы рассказать об опыте применения практик DDD к существующему Ruby on Rails проекту. Изначально, мы имели монолит, который писался 10 лет. Основная трудность проекта была в достаточно сложных процессах, и высокой связанности. Нам удалось не только декомпозировать приложение на отдельные сервисы, но и существенно повысить читаемость кода, сделать описываемые процессы прозрачными.


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


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


    Тезаурус


    Тезаурус — словарь терминов, использующийся для описания конкретной предметной области.

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


    Задача решаемая в рамках данного подхода


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


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


    Давайте распишем эту задачу более подробно.


    Почему возникает необходимость переписывать проект?


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


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


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

    Например:


    • Компания делает продукт для потребителей или оказывает услугу.
    • Лаборатория ведет разработку нового лекарства.
    • Школа занимается обучением.
    • Городской архив предоставляет информацию гражданам.
    • Лера радует своих поклонников отличной фигурой в социальной сети.

    В массовом случае бизнес строится вокруг идеи извлечь прибыль через удовлетворение потребностей своих клиентов. Чтобы извлекаемая прибыль увеличивалась, необходимо удовлетворять актуальные Потребности клиента большим количеством качественных решений. Данная идея описана как первый принцип Agile манифеста, хотя идея и не нова. То, что потребности лежат в основе нашего общества утверждали многие философы. Например, Платон попытался упорядочить потребности, создать их классификацию. Именно он называет главные формы экономических потребностей: питание, одежда, жилье. "Задача бизнеса" -удовлетворить потребности. А применяемые решения должны увеличить конкурентоспособность бизнеса.


    Конкурентоспособность — Преимущество одного бизнеса перед другим.

    Agile манифест также нам дает подсказку, что гибкость проекта повышается через его техническое совершенство и качество проектирования.


    Гафик 1: типичный проект


    Рассмотрим цикл поставки ценностей на примере "Типичного web-проекта"


    • t0 — у нас появилась идея.
    • t1 мы реализовали MVP. Тут немного отвлечемся:
      MVP minimum viable product (Минимально целесообразный продукт) — продукт, обладающий минимальными, но достаточными для удовлетворения первых потребителей, функциями. Основная задача — получение обратной связи для формирования гипотез дальнейшего развития продукта.

    Данный термин был популяризирован Стивом Бланком и Эриком Рисом. MVP является достаточно эффективным инструментом для того, чтобы опробовать вашу бизнес идею и ответить на главный вопрос "Взлетит — не взлетит?"


    Правильный ответ

    42


    • t2 — Вернемся к графику. Идея оказалась удачной, мы получили положительную обратную связь и смогли удовлетворить большое количество потребностей клиентов в указанное время.
    • t3 — В этот раз удовлетворение наступило в меньшей степени. Мы увеличили штат.
    • t4 — Мы поставили еще меньшее количество ценностей.
    • t5 — Если мы не начали Рефакторинг, то в это время бизнес перестает быть конкурентоспособным.

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


    График 2 - высокосвязанный проект


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


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


    График 3 - Деньги


    Интегралом (площадью под линией) будут заработанные деньги. Реальное приложение (Real app) заработает больше, чем "идеальное" (Academin app), по меньшей мере, до времени наступления энтропии — t4. Звучит хорошо, так и нужно делать.


    Но что делать в дальнейшем? Повторять рефакторинг до бесконечности невозможно. В какой-то момент времени объем кодовой базы достигнет такого уровня, что переписать "всё и сразу" будет затруднительно. И рано или поздно придется разбить проект на отдельные компоненты:


    График 4 - низкосвязанный проект


    Одним из подходов к реализации сложным систем является DDD:


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

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


    Данный паттерн может быть реализован через пространство имен (namespace), и через микросервисы. Мы будем использовать и ту и другую реализацию, в зависимости от уровня связанности контекстов. Что в конечном итоге приведет к созданию декомпозированного, сегментированного приложения.


    График 5 - Сегментироанный проект


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


    Поддержка проекта


    В рамках поддержки проекта нужно обеспечить ряд вещей.


    • Поставка ценностей: Scrum, Agile, работа с клиентами, Continuous delivery.
    • Снижение уровня энтропии: DDD, Micro-service как один из способов разделения контекстов, документация.
    • Качество кода: Проектирование на доменном уровне, TDD, BDD.
    • Качество продукта: Ручное и автоматизированное тестирование, багтреккинг, логирование.
    • Доступность продукта: Дублирование систем.
    • Скорость продукта: Горизонтальное масштабирование.
    • Удержание команды разработчиков: Система мотивации, открытость, честность.

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


    Следует помнить, что порог вхождения в сложную систему достаточно высок, поэтому важно обеспечить обучение кадров. Также, если мы хотим работать без сбоев, у нас не должно быть "незаменимых" специалистов, и поэтому нужно обеспечить полную взаимозаменяемость всех ролей. Если у вас вылетел из команды 'специалист по Continuous delivery' — нужна его замена. Если замена не может быть обеспечена, то не стоит вводить стек технологий в "production" без обеспечения достаточной поддержки.


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


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


    Кратко


    • Если у вас задача реализовать MVP — начните с Ruby On Rails.
    • Если MVP взлетел и идея оправдалась, сделайте первый рефакторинг, "облегчите" свои модели при помощи сервисов, декораторов, вынесите валидацию и слой работы с БД из моделей в отдельные концерны. Напишите тесты, документацию.
    • Если у вас у вас не такой сложный проект и можно убрать энтропию оптимизацией моделей — сделайте это.
    • Если у вас логичный, читаемый проект, и вам требуется повысить его производительность, при этом его можно разделить, скажем, по пользователям, то используйте масштабирование. Но не пытайтесь разорвать проект на сервисы по доменам.
    • Если у вас "сложный" бизнес и вы ищете инструмент, чтобы выйти в онлайн (почему вы это еще не сделали ?!) — рассмотрите также готовые "Enterprise решения", скажем, на java или .NET. Описанные практики зарождались в подобных решениях и они имеют богатый готовый инструментарий, что позволит вам сэкономить деньги.
    • Если ваш проект на ruby, у вас штат ruby программистов, проект содержит сложную бизнес логику, готовится к нагрузке или уже нагружен, и энтропия возросла настолько, что переписать очень и очень сложно, то вам стоит рассмотреть возможность применения подхода DDD и Микросервисы.



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




    Источники вдохновения:


    Поделиться публикацией

    Похожие публикации

    Комментарии 2
      0
      Enterprice-> Enterprise
        0
        Спасибо за замечание, исправил.

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

      Самое читаемое