Реализация на уровне домена на уровне кода

задняя часть
Реализация на уровне домена на уровне кода

Автор Ян Тао имеет 12-летний опыт работы в интернет-индустрии и 8-летний опыт технического менеджмента. Он успешно занимался поиском, социальными сетями, онлайн-образованием, электронной коммерцией и другими отраслями, и накопил обширный опыт в решениях для высокой параллелизма и сложных бизнес-сценариев.

задний план

Xiaomi Youpin запустила систему членства с развитием своего бизнеса. Он включает в себя такие бизнес-сценарии, как скидки за 5 заказов, подарочные пакеты при открытии карты, ежемесячные купоны, членские цены, приоритетные покупки и другие права и преимущества. В ходе начального процесса исследования спроса была выявлена ​​сложность системы членства для бизнеса. Согласно плану, в будущем бизнесе будет горизонтальное и вертикальное расширение (например, горизонтальное увеличение прав, множественное членство, вертикальная иерархия и т. д.).

Особенности бизнеса и проблемы

  • Сфера влияния широка, и права членства охватывают почти все основные бизнес-сценарии, такие как продуктовые станции, корзины покупок, страницы оформления заказа, страницы мест проведения и каналы членства.

  • Логика сложная, видов прав много, и состояний много (например, состояний возврата около 15, в будущем их будет больше)

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

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

Почему стоит выбрать «Управление доменом»

  1. Центр членства позиционируется как мидл-офисная служба.Команда также накопила некоторый опыт в управлении доменами.Кроме того, для точного и быстрого осуществления такого сложного бизнеса, а также для удовлетворения различных потребностей последующего расширения, управление доменами стало лучшим выбор на данный момент..
  2. Для краткости Domain-Driven Design (DDD) — это идеология разработки, направленная на проектирование и управление программным обеспечением, написанным в сложных предметных областях, предложенная Эриком Эвансом в 2003 году. По разным причинам он не получил широкого распространения в Китае, но некоторые понятия уже появились в нашей повседневной работе, такие как XxxEntity, XxxRepository, XxxService, XxxFactory, которые мы видим в коде.
  3. Он имеет высокую теоретическую сложность и высокую стоимость обучения и не использовался широко в Китае до появления микросервисов и промежуточных платформ. Концепции домена, такие как домен и ограниченный контекст, естественным образом подготовлены для разделения и управления сервисами. Однако ведь это была концепция, предложенная 18 лет назад.Первоначальный DDD сейчас не в полной мере применим.Нужно использовать методы анализа и моделирования, такие как шторм событий и четырехцветное моделирование.
  4. После стольких лет разработки микросервисов связанные с ними теории архитектуры становятся все более и более зрелыми, и широко используются инженерные методы, такие как штормы событий и гибкие итерации.Смотреть на драйверы домена уже не так сложно.Вы даже можете проектировать соответствующие проекты в соответствии с вашими характеристиками проекта собственный план реализации.

Сравнение парадигм разработки корпоративных приложений: на основе данных, на основе функций и на основе предметной области:

图片

процитировано из:У-у-у. То же самое. IO/01/06/2016/…

Как должен быть реализован доменный диск?

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

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

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

图片 процитировано из:Праведность Следующая остановка/обзор…

Что касается архитектуры, вы можете выбрать (или комбинировать) многоуровневую архитектуру DDD, шестиугольную архитектуру, аккуратную архитектуру и т. д. Конкретный выбор зависит от конкретного бизнес-сценария или общего архитектурного стиля.

От примера, чтобы увидеть реализацию до уровня кода

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

Члены моей команды в основном проектировали и разрабатывали на основе управляемых данными или применяли спецификации модели домена Али (DO, DTO, BO, AO, VO, Query), поэтому мы решили сначала реализовать многоуровневую архитектуру DDD, а затем следовать Upgrade as. нужный.

 1. Схема многоуровневой архитектуры DDD

图片

2. На лестничной площадке есть два места на картинке, на которые стоит обратить внимание:

① Бизнес-логика может существовать только на уровне домена и на уровне приложения, а уровень приложения может вызываться только через несколько поддоменов.Основная бизнес-логика реализована на уровне домена в соответствии со спецификацией, управляемой доменом. Нарушение этого принципа приведет к тому, что большая часть бизнес-логики будет «выжата» на прикладном уровне.

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

3. Описание каждого слоя (снизу вверх)

Слой инфраструктуры:Никакой бизнес-логики. К ним относятся различные пулы соединений (mysql, redis и т. д.), различные конфигурации (подключение к центру конфигурации, подключение к глобальному уникальному или подключение к другим службам промежуточного программного обеспечения группы), утилиты внутри проекта, библиотеки ресурсов (базы данных, redis, локальные кеши и т.д.); Строго говоря, доступ к хранилищу данных (библиотеке ресурсов) тоже относится к инфраструктурному слою, включая кеш базы данных, redis и прочего промежуточного ПО, локальный кеш jvm и т.д., но для удобства разделения сервисов мы создавать соответствующие пакеты поддоменов в каждом пакете поддоменов Пакет библиотеки ресурсов, в котором хранится рабочий класс связанных данных в поддомене

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

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

Прикладной уровень:Межсубдоменные вызовы (например, межсубдоменные транзакции) могут быть запланированы на уровне приложения или инициированы событиями домена, подписками на сообщения других служб, агентами вызовов других служб (такими как интерфейсы RPC/Rest).

Уровень пользовательского интерфейса:Класс реализации, соответствующий API службы dubbo, и контроллер сети (если веб-проект использует моделирование предметной области).

4. Список структуры каталогов

图片

5. Используйте пример, чтобы связать вызовы каждого слоя (сверху вниз) «псевдокодом».

Уровень пользовательского интерфейса (класс реализации интерфейса) имеет метод:

com.xiaomi.youpin.member.service.interfaces.DemoServiceImpl#refund{
    //校验参数
    verifyParams(request); 
    //调用基础设施层做请求幂等性校验,重试1次,间隔50ms 
    IdempotentTools.try(request.getParamsForIdempotent(),() -> {        
        //调用应用层服务,执行具体业务        
        demoXxxxAppService.refund(request.getA(), request.getB());
    },1,50);
}

Метод соответствующего класса прикладного уровня (унифицированный суффикс AppService):

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
com.xiaomi.youpin.demo.service.application.service.Demodomain1AppService#refund{    
    //顺序调用两个子域的相关方法    
    Long xxId = demodomain1DomainService.invalid(a, b);     
    demodomain2DomainService.refund(a, xxId);
}

Есть 2 службы уровня домена (унифицированный суффикс DomainService), здесь в качестве примера используется demodomain1DomainService:

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
com.xiaomi.youpin.member.service.domains.demodomain1.service.Demodomain1DomainService#invalid{ 
    //从资源库中查询数据对象    .
    ..domains.demodomain1.repository.dao.mysql.bean.DbDemoUser dbDemoUser = demodomain1UserRepository.findById(a);    
    //使用防腐层将数据对象转换为领域实体
    ...domains.demodomain1.aggregate.entity.DemoUser demoUser = DemoUserAdapter.parseToDemoUser(dbDemoUser);    
    //将此领域实体作为聚合根,创建对应聚合    
    ...domains.demodomain1.aggregate.DemoUserAggregate demoUserAggregate = DemoUserAggregate.builder().setAggregateRoot(demoUser).setUserRepository(memberUserRepository).build();    
    //调用聚合类的业务方法,执行具体的业务处理    
    demoUser = demoUserAggregate.invalid(b);    
    //后续流程(可以直接访问Repository)    
    Long vvvId = demodomain1VVVRepository.vvv(a, demoUser.getUid, demoUser.getStatus());    return vvvId;
}

Возьмем в качестве примера Demodomain1UserRepository доменной службы demodomain1.

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
com.xiaomi.youpin.demo.service.domains.demodomain1.repository.Demodomain1UserRepository#update{    
    //更新数据    
    demoUserDbDao.update(dbDemoUser);    
    //DbDemoUserSummary类是资源库内部使用的类,在资源库内部转换    ...domains.demodomain1.repository.dao.mysql.bean.DbDemoUserSummary summaryInfo = dbDemoUser.getSummaryInfo();    
    //刷新简要信息缓存    
    refreshSummaryCache(summaryInfo );}private void refreshSummaryCache(long a,int b){    //更新redis缓存    
    demoUserRedisCacheDao.refreshCache(refresh);    
    //这里只是示例,不讨论本地缓存的分布式数据同步问题    demoUserJvmCacheDao.refreshCache(refresh);
}

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

резюме и понимание

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

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

Domain-driven — это не серебряная пуля, и сложность проекта невысокая, использовать DDD не рекомендуется, также не рекомендуется пропускать обучение и напрямую использовать простые проекты для практики.

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