微信公众号:bugstack虫洞栈 领取驱动设计DDD{Domain-Driven Design}历史较长但随着微服务的兴起DDD又活跃到人们的视线,它提供的是一套架构设计思想,我们可以使用这套方法论将架构设计的尽可能做到高内聚、低耦合、可扩展性强的应用服务。本专题以DDD实战落地为根本,分章节设计不同的架构模型。学习并实战是奔入应用级最快的方法,Hi HelloWorld!我来了。
DDD(Domain-Driven Design 领域驱动设计)是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建模,以应对系统规模过大时引起的软件复杂性的问题。整个过程大概是这样的,开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而复始,构建出一套符合当前领域的模型。
依靠领域驱动设计的设计思想,通过事件风暴建立领域模型,合理划分领域逻辑和物理边界,建立领域对象及服务矩阵和服务架构图,定义符合DDD分层架构思想的代码结构模型,保证业务模型与代码模型的一致性。通过上述设计思想、方法和过程,指导团队按照DDD设计思想完成微服务设计和开发。 1、拒绝泥球小单体、拒绝污染功能与服务、拒绝一加功能排期一个月 2、架构出高可用极易符合互联网高速迭代的应用服务 3、物料化、组装化、可编排的服务,提高人效
应用层{application}
领域层{domain}
基础层{infrastructrue}
接口层{interfaces}
1、jdk1.8【jdk1.7以下只能部分支持netty】 2、springboot 2.0.6.RELEASE 3、idea + maven
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 复制代码
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; } } 复制代码
infrastructure/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); } } 复制代码