Особый случай DDD, случай 1 «Введение в доменно-ориентированное проектирование DDD Landing»

Дизайн, управляемый доменом
Особый случай DDD, случай 1 «Введение в доменно-ориентированное проектирование DDD Landing»

Публичный аккаунт WeChat: стек червоточины bugstack DDD {Domain-Driven Design} имеет долгую историю, но с появлением микросервисов DDD стал более активно привлекать внимание людей. Он предоставляет набор идей архитектурного дизайна. Мы можем использовать эту методологию для проектирования архитектуры в максимально возможной степени. , Добейтесь высокой степени согласованности, низкой связанности и высокой масштабируемости служб приложений. Этот раздел основан на реальной реализации DDD, и в главах разрабатываются различные архитектурные модели. Обучение и борьба — самый быстрый способ войти в прикладной уровень, Hi HelloWorld! Я иду.

Введение

DDD (Domain-Driven Design Domain-Driven Design) был впервые предложен Эриком Эвансом, цель которого состоит в том, чтобы смоделировать домен, связанный с программным обеспечением, чтобы решить проблему сложности программного обеспечения, вызванную большим масштабом системы. Весь процесс примерно таков: команда разработчиков и эксперты в предметной области используют Ubiquitous Language для понимания и усвоения знаний предметной области, извлечения и разделения знаний предметной области на поддомены (основной поддомен, общий поддомен, вспомогательный поддомен). ) и создайте модель в поддомене, а затем повторите описанные выше шаги, чтобы создать набор моделей, соответствующих текущему домену.

微信公众号:bugstack虫洞栈 | DDD概述

цели развития

Опираясь на идею проектирования, ориентированного на предметную область, создайте модель предметной области посредством штормов событий, разумно разделите логику предметной области и физические границы, установите объекты предметной области, матрицы служб и диаграммы архитектуры служб, определите модель структуры кода, которая соответствует Идея многоуровневой архитектуры DDD и обеспечение согласованности бизнес-моделей с моделью кода. С помощью приведенных выше дизайнерских идей, методов и процессов помогите команде завершить проектирование и разработку микросервисов в соответствии с идеей дизайна DDD. 1. Откажитесь от небольших мономеров из грязевых комков, откажитесь от загрязнения функций и услуг и откажитесь от планирования функций «один плюс» на один месяц. 2. Спроектируйте сервисы приложений с высокой доступностью, которые легко справятся с высокоскоростной итерацией Интернета. 3. Материализованные, собранные и организованные услуги для повышения эффективности работы персонала.

Сервисная архитектура

微信公众号:bugstack虫洞栈 | 服务架构

  • прикладной уровень {приложение}

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

    • Доменные службы расположены на доменном уровне и являются инкапсулированными службами для выполнения преобразования операций между сущностями или объектами-значениями в домене.Доменные службы участвуют в процессе реализации так же, как сущности и объекты-значения.
    • Доменные службы объединяют и инкапсулируют один или несколько методов одного и того же объекта или комбинируют или организуют операции нескольких разных сущностей и предоставляют их как доменные службы. Доменные службы инкапсулируют основную бизнес-логику. Поведение самой сущности реализуется внутри класса сущности и инкапсулируется вверх как доступ к доменной службе.
    • Чтобы скрыть реализацию бизнес-логики уровня предметной области, все методы и службы предметной области должны быть доступны через службы предметной области.
    • Для обеспечения разделения агрегатов внутри микрослужб в принципе запрещены вызовы межагрегатных доменных служб и межагрегатная корреляция данных.
  • базовый уровень {инфраструктура}

    • Основные службы расположены на базовом уровне. Предоставляйте службы ресурсов (такие как базы данных, кэши и т. д.) для каждого уровня, реализовывайте развязку каждого уровня и уменьшайте влияние изменений внешних ресурсов на бизнес-логику.
    • Базовые службы в основном представляют собой службы хранилища, которые предоставляют базовые службы ресурсов для каждого уровня посредством инверсии зависимостей.Доменные службы и службы приложений вызывают интерфейсы служб хранилища и используют хранилища для реализации постоянных объектов данных или прямого доступа к базовым ресурсам.
  • уровень интерфейса {интерфейсы}

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

среда разработки

1. jdk1.8 [только частично поддерживается netty ниже jdk1.7] 2. пружинная загрузка 2.0.6.РЕЛИЗ 3. идея + мавен

пример кода

itstack-demo-ddd-01
└── src
    ├── main
    │   ├── java
    │   │   └── org.itstack.demo
    │   │       ├── application
    │   │       │	├── event
    │   │       │	│   └── ApplicationRunner.java	
    │   │       │	└── service
    │   │       │	    └── UserService.java	
    │   │       ├── domain
    │   │       │	├── model
    │   │       │	│   ├── aggregates
    │   │       │	│   │   └── UserRichInfo.java	
    │   │       │	│   └── vo
    │   │       │	│       ├── UserInfo.java	
    │   │       │	│       └── UserSchool.java	
    │   │       │	├── repository
    │   │       │	│   └── IuserRepository.java	
    │   │       │	└── service
    │   │       │	    └── UserServiceImpl.java	
    │   │       ├── infrastructure
    │   │       │	├── dao
    │   │       │	│   ├── impl
    │   │       │	│   │   └── UserDaoImpl.java	
    │   │       │	│   └── UserDao.java	
    │   │       │	├── po
    │   │       │	│   └── UserEntity.java	
    │   │       │	├── repository
    │   │       │	│   ├── mysql
    │   │       │	│   │   └── UserMysqlRepository.java
    │   │       │	│   ├── redis
    │   │       │	│   │   └── UserRedisRepository.java		
    │   │       │	│   └── UserRepository.java	
    │   │       │	└── util
    │   │       │	    └── RdisUtil.java
    │   │       ├── interfaces
    │   │       │	├── dto
    │   │       │	│	└── UserInfoDto.java	
    │   │       │	└── facade
    │   │       │		└── DDDController.java
    │   │       └── DDDApplication.java
    │   ├── resources	
    │   │   └── application.yml
    │   └── webapp	
    │       └── WEB-INF
    │        	└── index.jsp	
    └── test
         └── java
             └── org.itstack.demo.test
                 └── ApiTest.java

Продемонстрируйте некоторые ключевые блоки кода, загрузите полный код и следуйте официальной учетной записи; стек червоточины багстека | Ответить приземление DDD

application/UserService.java | Пользовательский сервис прикладного уровня, сервис доменного уровня для конкретной реализации

/**
 * 应用层用户服务
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
public interface UserService {

    UserRichInfo queryUserInfoById(Long id);

}

domain/repository/IuserRepository.java | Репозиторий уровня домена, реализованный базовым уровнем

/**
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
public interface IUserRepository {

    void save(UserEntity userEntity);

    UserEntity query(Long id);

}

domain/service/UserServiceImpl.java | Класс реализации прикладного уровня, прикладной уровень — это очень тонкий слой, который может выполнять только оркестровку служб.

/**
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource(name = "userRepository")
    private IUserRepository userRepository;

    @Override
    public UserRichInfo queryUserInfoById(Long id) {
        
        // 查询资源库
        UserEntity userEntity = userRepository.query(id);

        UserInfo userInfo = new UserInfo();
        userInfo.setName(userEntity.getName());

        // TODO 查询学校信息,外部接口
        UserSchool userSchool_01 = new UserSchool();
        userSchool_01.setSchoolName("振华高级实验中学");

        UserSchool userSchool_02 = new UserSchool();
        userSchool_02.setSchoolName("东北电力大学");

        List<UserSchool> userSchoolList = new ArrayList<>();
        userSchoolList.add(userSchool_01);
        userSchoolList.add(userSchool_02);

        UserRichInfo userRichInfo = new UserRichInfo();
        userRichInfo.setUserInfo(userInfo);
        userRichInfo.setUserSchoolList(userSchoolList);

        return userRichInfo;
    }

}

инфраструктура/po/UserEntity.java | класс объекта базы данных

/**
 * 数据库实体对象;用户实体
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
public class UserEntity {

    private Long id;
    private String name;

    get/set ...
}

infrastructrue/repository/UserRepository.java | Интерфейс определения уровня домена, реализация репозитория базового уровня

/**
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
@Repository("userRepository")
public class UserRepository implements IUserRepository {

    @Resource(name = "userMysqlRepository")
    private IUserRepository userMysqlRepository;

    @Resource(name = "userRedisRepository")
    private IUserRepository userRedisRepository;

    @Override
    public void save(UserEntity userEntity) {
        //保存到DB
        userMysqlRepository.save(userEntity);

        //保存到Redis
        userRedisRepository.save(userEntity);
    }

    @Override
    public UserEntity query(Long id) {

        UserEntity userEntityRedis = userRedisRepository.query(id);
        if (null != userEntityRedis) return userEntityRedis;

        UserEntity userEntityMysql = userMysqlRepository.query(id);
        if (null != userEntityMysql){
            //保存到Redis
            userRedisRepository.save(userEntityMysql);
            return userEntityMysql;
        }

        // 查询为NULL
        return null;
    }

}

interfaces/dto/UserInfoDto.java|Класс объекта DTO, класс изолированной базы данных

/**
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
public class UserInfoDto {

    private Long id;        // ID

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

interfaces/facade/DDDController.java|Фасадный интерфейс

/**
 * 虫洞栈:https://bugstack.cn
 * 公众号:bugstack虫洞栈 | 欢迎关注并获取更多专题案例源码
 * Create by fuzhengwei on @2019
 */
@Controller
public class DDDController {

    @Resource(name = "userService")
    private UserService userService;

    @RequestMapping("/index")
    public String index(Model model) {
        return "index";
    }

    @RequestMapping("/api/user/queryUserInfo")
    @ResponseBody
    public ResponseEntity queryUserInfo(@RequestBody UserInfoDto request) {
        return new ResponseEntity<>(userService.queryUserInfoById(request.getId()), HttpStatus.OK);
    }

}

Подводить итоги

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

微信公众号:bugstack虫洞栈,欢迎关注&获取源码