核心逻辑是,将程序中业务,领域知识的部分(domain or business logic)与负责流程控制、协调和决策的部分(control logic)分开,提高代码的可维护性,可测试性和复用性。
在 DDD 中,业务逻辑对应着领域逻辑,控制逻辑对应着「应用层」或「服务层」。
Business Logic
- 内容:业务规则、验证数据、计算公式
- 职责:确保系统行为符合业务需求和规范
- 示例:
- 计算订单的总价
- 判断用户的权限
- 业务状态的转换
Control Logic
- 内容:流程控制、调用顺序、条件判断
- 职责:组织和管理业务逻辑的执行,保证系统流程正确
- 示例:
- 处理多步骤业务流程的状态切换
- 事务开始和提交控制
示例
用 Python
普通写法
class UserService:
def __init__(self):
self.users = []
def register_user(self, username, password):
# 1. validate username
if username in self.users:
return {"success": False, "message": "Username already exists"}
# 2. validate password length
if len(password) < 6:
return "Password too short"
# 3. store user
self.users.append(username)
return {"success": True, "message": "User registered successfully"}
分离后写法
class UserRepository:
def __init__(self):
self.users = {}
def exists(self, username):
return username in self.users
def save(self, user):
self.users[user["username"]] = user
# Domain Logic
class UserDomainService:
def __init__(self, user_repository):
self.user_repository = user_repository
def is_username_available(self, username):
# Check if the username is already taken
return self.user_repository.exists(username)
def validate_password(self, password):
# Validate the password according to your criteria
return len(password) >= 6
def create_user(self, username, password):
user = {"username": username, "password": password}
self.user_repository.save(user)
return user
# Application Logic
class UserApplicationService:
def __init__(self, user_domain_service):
self.user_domain_service = user_domain_service
def register_user(self, username, password):
# 1. Check if the username is available
if self.user_domain_service.is_username_available(username):
return {"success": False, "message": "Username already taken."}
# 2. Validate the password
if not self.user_domain_service.validate_password(password):
return {"success": False, "message": "Password does not meet criteria."}
# 3. Create the user
user = self.user_domain_service.create_user(username, password)
return {"success": True, "user": user}
repo = UserRepository()
domain_service = UserDomainService(repo)
app_service = UserApplicationService(domain_service)
print(app_service.register_user("john_doe", "password123")) # Should succeed
print(
app_service.register_user("john_doe", "pass")
) # Should fail due to password criteria
print(
app_service.register_user("john_doe", "newpassword")
) # Should fail due to username already taken
- UserDomainService 只关注业务规则(用户名是否存在、密码校验、创建用户)。
- UserApplicationService 负责流程控制(调用顺序、返回结果)。
用 Java
普通写法
import java.util.HashSet;
import java.util.Set;
public class UserService {
private Set<String> users = new HashSet<>();
public Result register(String username, String password) {
// 1. Check if the username is available
if (users.contains(username)) {
return new Result(false, "Username is already in use");
}
// 2. Validate the password
if (password.length() < 6) {
return new Result(false, "Password must be at least 6 characters");
}
// 3. Create the user
users.add(username);
return new Result(true, "success");
}
public static class Result {
private boolean success;
private String message;
public Result(boolean success, String message) {
this.success = success;
this.message = message;
}
public boolean isSuccess() {return success;}
public String getMessage() {return message;}
}
}
分离后写法
import java.util.HashMap;
import java.util.Map;
// Domain Logic
class UserDomainService {
private UserRepository userRepository;
public UserDomainService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public boolean isUsernameTaken(String username) {
return userRepository.exists(username);
}
public boolean validatePassword(String password){
return password != null && password.length() >= 6;
}
public void createUser(String username, String password) {
User user = new User(username, password);
userRepository.save(user);
}
}
// Persistence Layer
class UserRepository{
private Map<String, User> users = new HashMap<>();
public boolean exists(String username){
return users.containsKey(username);
}
public void save(User user){
users.put(user.getUsername(), user);
}
}
// User Entity
class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
}
class Result {
private boolean success;
private String message;
public Result(boolean success, String message) {
this.success = success;
this.message = message;
}
public boolean isSuccess() {return success;}
public String getMessage() {return message;}
}
// Application Logic
class UserApplicationService {
private UserDomainService userDomainService;
public UserApplicationService(UserDomainService userDomainService) {
this.userDomainService = userDomainService;
}
public Result register(String username, String password) {
if(userDomainService.isUsernameTaken(username))
return new Result(false, "Username taken");
if(!userDomainService.validatePassword(password))
return new Result(false, "Invalid password");
userDomainService.createUser(username, password);
return new Result(true, "success");
}
}
public class scratch_46 {
public static void main(String[] args) {
UserRepository userRepository = new UserRepository();
UserDomainService userDomainService = new UserDomainService(userRepository);
UserApplicationService userApplicationService = new UserApplicationService(userDomainService);
Result r1 = userApplicationService.register("alice", "12345");
System.out.println(r1.getMessage());
Result r2 = userApplicationService.register("alice", "123456");
System.out.println(r2.getMessage());
Result r3 = userApplicationService.register("alice", "1234567");
System.out.println(r3.getMessage());
}
}
- UserDomainService 负责业务规则(用户名是否存在、密码校验、创建用户)。
- UserApplicationService 负责控制流程(调用顺序、返回结果)。
- UserRepository 模拟数据存储。
- User 领域实体。
提示与建议
- 从简单方法开始构思
- 简单方法转换到逻辑控制层
- 分离出业务逻辑