客户端 ──┬── 策略接口(Strategy)
│ ├── 具体策略A
│ ├── 具体策略B
│ └── 具体策略C
│
└── 策略上下文(Context)
└── 持有/选择策略
// 1. 策略接口
public interface Strategy {
boolean supports(String context);
String execute(ContextData data);
}
// 2. 具体策略
@Component
public class ConcreteStrategyA implements Strategy {
@Override
public boolean supports(String resource) {
return "A".equals(resource);
}
@Override
public String execute(ContextData data) {
return "Result A";
}
}
// 3. 策略注册器/上下文
@Component
public class StrategyRegistry {
private final List<Strategy> strategies;
public String handle(String resource, ContextData data) {
return strategies.stream()
.filter(s -> s.supports(resource))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("无可用策略"))
.execute(data);
}
}
传统写法(不推荐):
public String formatLog(String resource, String action, Object[] args) {
switch (resource) {
case "user":
return String.format("用户操作: %s, 参数: %s", action, Arrays.toString(args));
case "role":
return String.format("角色操作: %s", action);
case "permission":
return String.format("权限操作: %s", action);
default:
return "未知操作";
}
}
策略模式重构后:
// Strategy 接口
public interface LogStrategy {
boolean supports(String resource);
String format(String action, Object[] args);
}
// 具体策略
@Component
public class UserLogStrategy implements LogStrategy {
@Override
public boolean supports(String resource) { return "user".equals(resource); }
@Override
public String format(String action, Object[] args) {
return "用户" + getActionName(action) + ",参数:" + Arrays.toString(args);
}
}
// 使用
@Service
public class LogService {
private final List<LogStrategy> strategies;
public String format(String resource, String action, Object[] args) {
return strategies.stream()
.filter(s -> s.supports(resource))
.findFirst()
.map(s -> s.format(action, args))
.orElse("未知操作");
}
}
客户端 ──┬── 处理器1 ── 处理器2 ── 处理器3 ── ... ── 末端处理器
│ │ │
└──────────┴──────────┴── (链式调用)
版本1:显式链(固定顺序)
// 处理器接口
public interface Handler {
void handle(Request request);
void setNext(Handler next);
}
// 具体处理器
public class HandlerA implements Handler {
private Handler next;
@Override
public void handle(Request request) {
if (shouldHandle(request)) {
process(request);
} else if (next != null) {
next.handle(request);
}
}
}
// 客户端组装链
Handler chain = new HandlerA();
chain.setNext(new HandlerB());
chain.setNext(new HandlerC());
chain.handle(request);
版本2:隐式链(自动扫描 + 顺序控制)
// 处理器接口(简化版)
public interface Validator {
int order();
void validate(Request request);
}
// 链管理器
@Component
public class ValidatorChain {
private final List<Validator> validators;
public void validate(Request request) {
validators.stream()
.sorted(Comparator.comparingInt(Validator::order))
.forEach(v -> v.validate(request));
}
}
需求:新用户注册需依次校验
传统写法(不推荐):
public void register(UserDTO dto) {
if (!dto.getUsername().matches("^[a-zA-Z0-9_]{3,20}$")) {
throw new BizException("用户名格式错误");
}
if (userService.exists(dto.getUsername())) {
throw new BizException("用户名已存在");
}
if (!isStrong(dto.getPassword())) {
throw new BizException("密码强度不足");
}
if (!EmailValidator.getInstance().isValid(dto.getEmail())) {
throw new BizException("邮箱格式错误");
}
// 业务逻辑...
}
责任链模式重构后:
// 1. 校验器接口
public interface UserRegisterValidator {
int order();
void validate(UserDTO dto) throws ValidationException;
}
// 2. 实现类
@Component
public class UsernameFormatValidator implements UserRegisterValidator {
@Override public int order() { return 1; }
@Override
public void validate(UserDTO dto) {
if (!dto.getUsername().matches("^[a-zA-Z0-9_]{3,20}$")) {
throw new ValidationException("用户名格式错误");
}
}
}
@Component
public class UsernameUniqueValidator implements UserRegisterValidator {
@Override public int order() { return 2; }
@Override
public void validate(UserDTO dto) {
if (userService.exists(dto.getUsername())) {
throw new ValidationException("用户名已存在");
}
}
}
// 3. 链管理器(自动组装)
@Component
public class ValidatorChain {
private final List<UserRegisterValidator> validators;
public void validate(UserDTO dto) {
validators.stream()
.sorted(Comparator.comparingInt(UserRegisterValidator::order))
.forEach(v -> v.validate(dto));
}
}
// 4. 使用
@Service
public class UserService {
private final ValidatorChain validatorChain;
public void register(UserDTO dto) {
validatorChain.validate(dto); // 自动按顺序执行
// 业务逻辑...
}
}
调用者 (Invoker) ──┬── Command(命令接口)
│ ├── ConcreteCommandA
│ └── ConcreteCommandB
│
└──► 接收者 (Receiver)
├── 方法A()
└── 方法B()
简单版本(内存栈)
// 1. 命令接口
public interface Command {
void execute();
void undo();
}
// 2. 具体命令
public class GrantPermissionsCommand implements Command {
private final RoleService roleService;
private final Long roleId;
private final List<Long> permissionIds;
public GrantPermissionsCommand(RoleService roleService, Long roleId, List<Long> permissionIds) {
this.roleService = roleService;
this.roleId = roleId;
this.permissionIds = permissionIds;
}
@Override
public void execute() {
roleService.grant(roleId, permissionIds);
}
@Override
public void undo() {
roleService.revoke(roleId, permissionIds);
}
}
// 3. 调用器(维护历史栈)
@Component
public class CommandInvoker {
private final Deque<Command> history = new ArrayDeque<>();
public void execute(Command command) {
command.execute();
history.push(command);
}
public void undo() {
if (history.isEmpty()) throw new IllegalStateException("无历史记录");
Command command = history.pop();
command.undo();
}
}
持久化版本(数据库记录)
// 命令历史实体(用于持久化)
@Entity
public class CommandHistory {
private Long id;
private String type; // "grant" / "revoke"
private String payload; // JSON 序列化的参数
private String status; // "done" / "undone"
}
// Invoker(存储到数据库)
@Component
public class CommandInvoker {
private final CommandHistoryRepository historyRepo;
public void execute(Command command, String type, List<Long> args) {
command.execute();
historyRepo.save(new CommandHistory(type, toJson(args), "done"));
}
public void undo() {
CommandHistory last = historyRepo.findTopByStatusOrderByIdDesc("done");
Command command = rebuild(record); // 反序列化重建命令
command.undo();
record.setStatus("undone");
historyRepo.save(record);
}
}
需求:
传统写法(问题):
public void grantPermissions(Long roleId, List<Long> permissionIds) {
Role role = roleRepository.findById(roleId);
rolePermissionRepository.deleteByRoleId(roleId);
rolePermissionRepository.batchInsert(roleId, permissionIds);
}
//撤销?不知道之前是什么状态,无法回退
命令模式解决方案:
// 1. 命令接口
public interface RolePermissionCommand {
void execute();
void undo();
}
// 2. 授权命令
public class GrantCommand implements RolePermissionCommand {
private final RolePermissionService service;
private final Long roleId;
private final List<Long> permissionIds;
@Override
public void execute() {
service.insert(roleId, permissionIds);
}
@Override
public void undo() {
service.delete(roleId, permissionIds);
}
}
// 3. 撤权命令
public class RevokeCommand implements RolePermissionCommand {
private final RolePermissionService service;
private final Long roleId;
private final List<Long> permissionIds;
@Override
public void execute() {
service.delete(roleId, permissionIds);
}
@Override
public void undo() {
service.insert(roleId, permissionIds);
}
}
// 4. 调用器(持久化版)
@Component
public class RolePermissionInvoker {
private final CommandHistoryRepository historyRepo;
private final RolePermissionService service;
public void grant(Long roleId, List<Long> permissionIds) {
GrantCommand cmd = new GrantCommand(service, roleId, permissionIds);
executeAndRecord(cmd, roleId, "grant", permissionIds);
}
public void undo(Long roleId) {
CommandHistory last = historyRepo.findTopByRoleIdAndStatusOrderByIdDesc(
roleId, "done");
if (last == null) throw new IllegalStateException("无历史记录");
RolePermissionCommand cmd = rebuildFromHistory(last);
cmd.undo();
last.setStatus("undone");
historyRepo.save(last);
}
private void executeAndRecord(RolePermissionCommand cmd, Long roleId,
String type, List<Long> permissionIds) {
cmd.execute();
historyRepo.save(new CommandHistory(roleId, type,
toJson(permissionIds), "done"));
}
}
| 维度 | 策略模式 | 责任链模式 | 命令模式 |
|---|---|---|---|
| 核心思想 | 封装算法,可互换 | 请求沿链传递,直到被处理 | 请求封装为对象 |
| 耦合关系 | 客户端 → 策略接口 | 客户端 → 链头(不感知后续) | 调用者 → 命令 → 接收者 |
| 对象间的联系 | 策略之间相互独立 | 有明确的父子链 | 命令持有接收者引用 |
| 典型场景 | 多种算法切换 | 多层审批、过滤器链 | 撤销重做、事务补偿 |
| 参数传递 | 上下文对象 | 沿链向下传递 | 构造函数注入命令对象 |