工厂模式
工厂类中,新建一个Map,用于存储不同日志记录类型中,所有已经实现了策略模式接口所对应策略的子类的对象
其中有一个getStrategies()
方法,通过传入策略接口实现类的名称,获取实现了策略模式接口的子类的对象
原因
因为日志记录是通过AOP方式进行采集记录,再加上有很多种日志类型和模块,并不清楚AOP中拿到的Class类对应的策略接口子类对象是什么
java
/**
* @author Zhoujinpeng
* @version 1.0.0
* @Description 风控预警------策略工厂类
* @createTime 2022年08月22日 11:13
*/
@Component
public class StrategyFactory<T> {
@Autowired
private Map<String, RiskControlOperationStrategy<T>> strategyMap;
public RiskControlOperationStrategy<T> getStrategies(String strategyName) {
return strategyMap.get(strategyName);
}
}
策略模式
首先是AOP中进入策略模式的入口:RiskControlOperationStrategyContext
java
/**
* @author Zhoujinpeng
* @version 1.0.0
* @Description 风控预警------操作日志策略环境
* @createTime 2022年08月19日 10:19
*/
@Component(value = "RiskControlOperationStrategyContext")
public class RiskControlOperationStrategyContext {
@Autowired
private StrategyFactory strategyFactory;
public CompareExecution executionStrategy(Object param) throws Exception {
CompareExecution compareExecution = null;
RiskControlStrategyEnum riskControlStrategyEnum = RiskControlStrategyEnum.of(param);
if (null != riskControlStrategyEnum) {
RiskControlOperationStrategy strategies = strategyFactory.getStrategies(riskControlStrategyEnum.getStrategyName());
compareExecution = strategies.getInformation(param);
}
return compareExecution;
}
}
以上是策略模式的Context上下文类,executionStrategy()
方法传入的就是AOP中拿到的Class类
java
// 接口调用参数
Object paramArg = args[0];
// 获取调用方法参数的Class
Class<?> paramArgClass = paramArg.getClass();
能够看到在类中引用了StrategyFactory
在executionStrategy
方法中,用到了一个RiskControlStrategyEnum
枚举类
java
/**
* @author Zhoujinpeng
* @version 1.0.0
* @Description
* @createTime 2022年08月30日 14:41
*/
public enum RiskControlStrategyEnum {
/**
* 规则
*/
RULES("RiskControlRuleDto", "RiskControlRuleOperationStrategy"),
/**
* 字段
*/
META("RiskControlBlackAndWhiteMetaParam", "RiskControlMetaOperationStrategy"),
/**
* 记录
*/
RECORD("RiskControlBlackAndWhiteRecordsParam", "RiskControlRecordsOperationStrategy"),
/**
* 消息
*/
MESSAGE("MessageTemplateDTO", "RiskControlMessageOperationStrategy"),
/**
* 指标
*/
TARGET("TargetDto", "RiskControlTargetOperationStrategy"),
/**
* 风控字段
*/
FIELD("FieldMangerDto", "RiskControlFieldMangerOperationStrategy"),
/**
* 通讯录
*/
ADDRESS_BOOK("AddressBookDTO", "RiskControlAddressBookOperationStrategy"),
/**
* 模型
*/
RULE_REQUEST("RiskRuleRequest", "RiskModelPreItemOperationStrategy");
private String resourceObj;
private String strategyName;
RiskControlStrategyEnum(String resourceObj, String strategyName) {
this.resourceObj = resourceObj;
this.strategyName = strategyName;
}
public String getResourceObj() {
return resourceObj;
}
public void setResourceObj(String resourceObj) {
this.resourceObj = resourceObj;
}
public String getStrategyName() {
return strategyName;
}
public void setStrategyName(String strategyName) {
this.strategyName = strategyName;
}
public static RiskControlStrategyEnum of(Object obj) {
return Arrays.stream(RiskControlStrategyEnum.values()).filter(item -> item.resourceObj.equals(obj.getClass().getSimpleName())).findFirst().orElse(null);
}
}
这个枚举类中,创建了很多类型的枚举,每一个枚举对应了一个日志记录的类型
其中还有一个很重要的,就是of()
方法。这个方法中,接到参数Class的Object对象,使用getSimpleName()
拿到这个对象的简写名称进行比较,比较出的结果即是枚举类型,也就是日志记录的类型
java
//得到类的简写名称
System.out.println(Sample.class.getSimpleName());
//得到对象的全路径
System.out.println(Sample.class);
//得到对象的类模板示例,也就是Class
System.out.println(Sample.class.getClass());
//得到Class类的名称
System.out.println(Sample.class.getClass().getName());
之后回到上下文类当中。拿到枚举类型后,获得了枚举类型中的策略接口实现类的名称
这是策略接口
java
/**
* @author Zhoujinpeng
* @version 1.0.0
* @Description 风控管理------操作日志策略
* @createTime 2022年08月18日 18:39
*/
@Component(value = "RiskControlOperationStrategy")
public interface RiskControlOperationStrategy<T> {
/**
* 获取操作前的历史数据
*
* @param t 传入的更改后的数据
* @return 与历史数据比较的结果
*/
CompareExecution getInformation(T t) throws Exception;
}
其中一个实现类
java
/**
* @author Zhoujinpeng
* @version 1.0.0
* @Description
* @createTime 2022年08月19日 11:29
*/
@Slf4j
@Component(value = "RiskControlMetaOperationStrategy")
public class RiskControlMetaOperationStrategy implements RiskControlOperationStrategy<RiskControlBlackAndWhiteMetaParam> {
@Resource
private BlackWhiteListMetaMapper blackWhiteListMetaMapper;
@Resource
private BlackAndWhiteListMapper blackAndWhiteListMapper;
@Override
public CompareExecution getInformation(RiskControlBlackAndWhiteMetaParam riskControlBlackAndWhiteMetaParam) throws Exception {
}
}
拿到的名称即是上面实现类的类名
利用这个策略实现类的名称(类名)调用工厂类中的方法,就能获得对应父类的引用。接着调用这个父类接口的方法,即可执行子类的实现的方法中去
java
RiskControlOperationStrategy strategies = strategyFactory.getStrategies(riskControlStrategyEnum.getStrategyName());
compareExecution = strategies.getInformation(param);