一、背景篇
在软件开发领域,随着业务需求的不断增长和复杂化,传统的单体架构逐渐暴露出扩展性差、维护困难等问题。
为应对这些挑战,微服务架构应运而生,核心思想是“分而治之”——将大型系统拆分为多个独立小型服务,每个服务专注特定业务功能,带来灵活性高、扩展性好、开发速度快等优势。
微服务面临的问题:
- 服务爆炸:拆分过细导致服务数量激增,管理维护成本上升。
- 拆分不合理:服务耦合度高,频繁重构调整。
- 数据一致性:分布式系统中微服务间数据一致性问题复杂化。
领域驱动设计(DDD)的激活:
- 由 Eric Evans 于2003年提出,因早期行业环境和复杂度不足未流行。
- 现用于解决微服务痛点,核心围绕领域对象、领域服务、领域事件等设计。
二、理论篇
2.1 DDD 的核心概念
1. 领域(Domain)
- 业务核心,包含业务规则、实体、流程等。
- 是软件设计核心,所有决策围绕领域进行。
2. 子域(Subdomain)
- 领域的一部分,对应业务特定功能或模块。
- 例:电商系统中订单管理、用户管理、库存管理等。
3. 实体(Entity)
- 具有唯一标识的对象,生命周期跨越多个业务操作,包含业务逻辑和状态。
4. 值对象(Value Object)
- 无唯一标识,用于表示业务概念中的值(如前端交互数据)。
5. 聚合(Aggregate)
- 一组相关实体和值对象的集合,作为整体操作。
- 聚合根(Aggregate Root):聚合入口点,维护内部一致性。
6. 领域服务(Domain Service)
- 封装不属于任何实体或值对象的业务逻辑。
7. 领域事件(Domain Event)
- 表示领域中发生的特定事件,通过发布/订阅实现业务解耦和系统扩展。
8. 仓储(Repository)
- 封装数据访问逻辑,提供聚合的持久化和查询操作,通常为接口,实现在基础设施层。
9. 防腐层(Anti-Corruption Layer)
- 保护领域模型不受外部模型影响,确保纯洁性,通常用适配器模式实现。
2.2 DDD 的四层架构
层级 | 职责描述 |
---|---|
用户界面层(Interface) | 处理用户交互,包含控制器(Controller)、视图(View)等组件。 |
应用层(Application) | 定义系统用例(Use Cases),不包含具体业务逻辑,依赖领域层完成操作。 |
领域层(Domain) | 包含业务逻辑、实体、值对象、领域服务、聚合、仓储接口等,是业务规则实现地。 |
基础设施层(Infrastructure) | 提供技术支持,如数据持久化、消息传递、外部服务调用,实现领域层仓储接口。 |
三、实战篇
系统功能:用户和角色的创建、修改、删除。
1. 项目结构
com └── company └── um ├── ddd-infrastructure (基础设施层) │ ├── dao │ │ ├── UserDAO.java │ │ └── RoleDAO.java │ ├── repository │ │ ├── UserRepository.java │ │ └── RoleRepository.java │ └── mapper │ ├── UserMapper.java │ └── RoleMapper.java ├── ddd-domain (领域层) │ ├── entity │ │ ├── User.java │ │ └── Role.java │ ├── factory │ │ └── UserFactory.java │ ├── service │ │ └── RoleAssignmentService.java │ ├── event │ │ └── UserCreatedEvent.java │ └── exception │ └── DomainException.java ├── ddd-application (应用层) │ ├── service │ │ ├── UserService.java │ │ └── RoleService.java │ └── dto │ ├── UserDTO.java │ └── RoleDTO.java └── ddd-interface (表示层) ├── controller │ └── UserController.java └── vo ├── UserVO.java └── RoleVO.java
2. 代码实现
2.1 基础设施层(ddd-infrastructure)
1.1 数据访问对象(DAO)
// UserDAO.java public interface UserDAO { void save(User user); User findById(Long id); void delete(User user); } // RoleDAO.java public interface RoleDAO { void save(Role role); Role findById(Long id); void delete(Role role); }
1.2 仓库(Repository)
// UserRepository.java public interface UserRepository { void save(User user); User findById(Long id); void delete(User user); } @Repository public class UserRepositoryImpl implements UserRepository { @Autowired private UserDAO userDAO; // 实现方法(save/findById/delete) } // RoleRepository.java(类似UserRepository实现)
1.3 映射器(Mapper)
// UserMapper.java public interface UserMapper { UserDTO toDTO(User user); User toEntity(UserDTO userDTO); } @Component public class UserMapperImpl implements UserMapper { // 属性映射逻辑(如id、name等) } // RoleMapper.java(类似UserMapper实现)
2.2 领域层(ddd-domain)
2.1 实体(Entity)
// User.java(聚合根) @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private Set<Role> roles = new HashSet<>(); // 添加/删除角色方法(维护聚合一致性) public void addRole(Role role) { ... } public void removeRole(Role role) { ... } } // Role.java(聚合内实体) @Entity public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToOne @JoinColumn(name = "user_id") private User user; }
2.2 工厂(Factory)
// UserFactory.java public class UserFactory { public static User createUser(Long id, String name) { User user = new User(); // 设置属性 return user; } }
2.3 领域服务(Domain Service)
// RoleAssignmentService.java public class RoleAssignmentService { public void assignRoleToUser(User user, Role role) { if (user.hasRole(role)) throw new DomainException("User already has the role"); user.addRole(role); } }
2.4 领域事件(Domain Event)
// UserCreatedEvent.java public class UserCreatedEvent extends Event { private User user; public UserCreatedEvent(User user) { this.user = user; } public User getUser() { return user; } }
2.5 领域异常(Domain Exception)
// DomainException.java public class DomainException extends RuntimeException { public DomainException(String message) { super(message); } }
2.3 应用层(ddd-application)
3.1 应用服务(Application Service)
// UserService.java public interface UserService { void createUser(UserDTO userDTO); void updateUser(UserDTO userDTO); void deleteUser(Long id); } @Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Autowired private UserMapper userMapper; @Autowired private EventPublisher eventPublisher; // 实现方法(调用领域层和基础设施层) } // RoleService.java(类似UserService实现)
3.2 数据传输对象(DTO)
// UserDTO.java public class UserDTO { private Long id; private String name; // getter/setter } // RoleDTO.java(类似UserDTO实现)
2.4 表示层(ddd-interface)
4.1 控制器(Controller)
// UserController.java @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @Autowired private UserMapper userMapper; @PostMapping public void createUser(@RequestBody UserDTO userDTO) { ... } @PutMapping public void updateUser(@RequestBody UserDTO userDTO) { ... } @DeleteMapping("/{id}") public void deleteUser(@PathVariable Long id) { ... } }
4.2 值对象(VO)
// UserVO.java(前端展示对象,属性与DTO类似) public class UserVO { private Long id; private String name; // getter/setter } // RoleVO.java(类似UserVO实现)
四、补充内容
1. 聚合与聚合根
- 聚合:业务一致性边界,聚合根(如
User
)负责维护内部实体(如Role
)关系。 - 示例代码:
@Entity public class User { // ... public void addRole(Role role) { roles.add(role); role.setUser(this); // 聚合根维护子实体关系 } }
2. 防腐层(Anti-Corruption Layer)
- 隔离外部系统(如JPA)对领域层的影响,通过适配器模式实现。
- 示例:
// 领域层DAO接口 public interface UserDAO { void save(User user); } // 基础设施层适配器(实现JPA交互) @Repository public class UserDAOJPAAdapter implements UserDAO { @PersistenceContext private EntityManager entityManager; public void save(User user) { entityManager.persist(user); } }