策略模式与工厂模式在AOP日志记录中的使用总结

工厂模式

工厂类中,新建一个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);
相关推荐
程序猿DD1 小时前
OctaFuse Gateway 2.15.0:MCP 聚合、向量 Embeddings 与官方目录同步
后端·agent
蛋蛋的就会顺顺的4 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
余槐i4 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
需要8264 小时前
Spring Bean 生命周期:从实例化到销毁的完整钩子
java·后端·spring
小 黄 鸡5 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
凤山老林5 小时前
Spring Boot 接入国密 SM2/SM3/SM4 的一些实践记录
spring boot·后端·python
伯恩bourne6 小时前
Spring Boot Bean 注册的两种方式:@Component 家族 vs @Configuration + @Bean
java·spring boot·后端
张彦峰ZYF7 小时前
停顿短不等于延迟低:G1、ZGC 与低延迟服务的目标分野、代价账本与选型标定
后端·回收暂停、应用停止总时长·到达安全点、分配停滞·屏障吃吞吐、并发线程吃核心·并发窗口吃堆余量·分区式靠挑回收集兑现目标·染色指针式不支持压缩引用
silvamux_7 小时前
curl 测试 OpenAI 兼容 API 的完整流程
java·人工智能·缓存·ai·oneapi
pride.li7 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉