一 定义策略类接口
import org.jetbrains.annotations.NotNull;import javax.annotation.Nullable;public interface ApprovalStrategy<T> {/*** 返回需要的类型 不能为空** @return*/@NotNullClass<T> getSupportedType();void handlePass(T businessId, @Nullable String comment);void handleReject(T businessId, String comment);
}
二 定义Context
import lombok.AllArgsConstructor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;import java.util.Map;@AllArgsConstructor
@Component
public class ApprovalContext {private final Map<String, ApprovalStrategy<?>> strategies;public <T> void executePass(String type, T businessId, @Nullable String comment) {ApprovalStrategy<T> strategy = getStrategyWithValidation(type);strategy.handlePass(convertBusinessId(strategy, businessId), comment);}public <T> void executeReject(String type, T businessId, String comment) {ApprovalStrategy<T> strategy = getStrategyWithValidation(type);strategy.handleReject(convertBusinessId(strategy, businessId), comment);}private <T> ApprovalStrategy<T> getStrategyWithValidation(String type) {@SuppressWarnings("unchecked")ApprovalStrategy<T> strategy = (ApprovalStrategy<T>) strategies.get(type);if (strategy == null) {throw new IllegalArgumentException("未知的审批类型:" + type);}return strategy;}private <T> T convertBusinessId(ApprovalStrategy<T> strategy, Object businessId) {Class<T> supportedType = strategy.getSupportedType();if (supportedType == null) {throw new NullPointerException("supportedType 不能为空");}if (!supportedType.isInstance(businessId)) {if (supportedType == Integer.class && businessId instanceof String) {return supportedType.cast(Integer.valueOf((String) businessId));} else {throw new IllegalArgumentException("不支持的类型转换:" + businessId.getClass() + " 到 " + supportedType);}}return supportedType.cast(businessId);}}
三 实现类
@Component("TEST_REVIEW")
@RequiredArgsConstructor
public class TestApproval implements ApprovalStrategy<Integer> {@Overridepublic void handlePass(Integer businessId, @Nullable String comment) {}@Overridepublic void handleReject(Integer businessId, String comment) {}@NotNull@Overridepublic Class<Integer> getSupportedType() {return Integer.class;}
}
这里TEST_REVIEW为ApprovalType枚举中的常量字符 利用spring将其收集到ApprovalContext类的strategies中
使用:
1 注入private final ApprovalContext approvalContext;
2 approvalContext.executePass(ApprovalType.TEST_REVIEW.name(), id, null);
|| approvalContext.executeReject(ApprovalType.TEST_REVIEW.name(), id, null);
这里可以用个枚举 来规范调用