一 定义策略类接口
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
public interface ApprovalStrategy<T> {
/**
* 返回需要的类型 不能为空
*
* @return
*/
@NotNull
Class<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> {
@Override
public void handlePass(Integer businessId, @Nullable String comment) {
}
@Override
public void handleReject(Integer businessId, String comment) {
}
@NotNull
@Override
public 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);
这里可以用个枚举 来规范调用