做者:小傅哥
博客:https://bugstack.cnhtml
沉澱、分享、成長,讓本身和他人都能有所收穫!
DDD(Domain-Driven Design 領域驅動設計)是由Eric Evans最早提出,目的是對軟件所涉及到的領域進行建模,以應對系統規模過大時引發的軟件複雜性的問題。整個過程大概是這樣的,開發團隊和領域專家一塊兒經過 通用語言(Ubiquitous Language)去理解和消化領域知識,從領域知識中提取和劃分爲一個一個的子領域(核心子域,通用子域,支撐子域),並在子領域上創建模型,再重複以上步驟,這樣周而復始,構建出一套符合當前領域的模型。
依靠領域驅動設計的設計思想,經過事件風暴創建領域模型,合理劃分領域邏輯和物理邊界,創建領域對象及服務矩陣和服務架構圖,定義符合DDD分層架構思想的代碼結構模型,保證業務模型與代碼模型的一致性。經過上述設計思想、方法和過程,指導團隊按照DDD設計思想完成微服務設計和開發。
一、拒絕泥球小單體、拒絕污染功能與服務、拒絕一加功能排期一個月
二、架構出高可用極易符合互聯網高速迭代的應用服務
三、物料化、組裝化、可編排的服務,提升人效java
應用層{application}mysql
領域層{domain}web
基礎層{infrastructrue}redis
接口層{interfaces}spring
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
演示部分重點代碼塊,完整代碼下載關注公衆號;bugstack蟲洞棧 | 回覆DDD落地sql
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); } }