策略模式在工作中的运用

这篇具有很好参考价值的文章主要介绍了策略模式在工作中的运用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在不同的场景下,执行不同的业务逻辑,在日常工作中是很寻常的事情。比如,订阅系统。在收到阿里云的回调事件、与收到AWS的回调事件,无论是收到的参数,还是执行的逻辑都可能是不同的。为了避免,每次新增一种场景,就要改变原有的代码结构,比如,改变原有逻辑,添加 if-else结构,一种可行的方案是,使用策略模式。

策略模式

贴个链接
简单来说,就是根据请求方的类型,执行特定的业务逻辑。

问题点

网络上大部分实现策略模式的代码,很多在将具体的策略注入到Map中时,是以硬编码的方式实现的,比如掘金上的这篇文章:如何优雅的将设计模式运用到实际项目中去?

在工作中借鉴,使用截图
这种方案,虽然可以实现策略模式,但是每次新增策略都要修改这个集合。期望的方案是,新增的策略,自动注入到map中,而不必手动添加。
策略模式在工作中的运用,策略模式,开发语言

为了解决新增策略时,要修改map的情况,调研之后,发现有两种方案:

  1. 美团文章推介的 基于单例的方式,每次启动时,自动将策略注入到map中。
  2. 掘金上另一种方案:基于注解+反射的方式,动态将策略加载到map中。

相比,美团的方案更加优秀,代码改动少,且性能高。不过,本次以方案2为例说明。

代码实现

业务场景

需要提供给外部云厂商回调API,当云服务发生告警时,调用此API,将告警事情同步到服务使用方。
考虑点:

  1. 因为每家厂商的回调参数各有不同,此时,需要定义一个回调对象基类,每个云厂商对应的回调对象继承这个基类,并实现添加其特定的属性。
  2. 因为API是放开到公网上的,因此,为了避免被攻击,除了从集团域名出去外,还对IP进行了频控,比如,调用次数100次/秒。

代码结构

策略模式在工作中的运用,策略模式,开发语言

具体代码

定义实体类

基类

import lombok.Data;

/**
 * @author wangbin16
 * @date 2024/1/18 15:33
 */
@Data
public class CloudAlertBase {
    /**
     * name = "alertType", value = "告警类型"
     */
    private Integer alertType;

    /**
     * 业务
     */
    private Integer business;
}

阿里云

import lombok.Data;

/**
 * 阿里云监控告警
 * @author wangbin16
 * @date 2024/1/18 15:35
 */
@Data
public class AliyunCloudAlertAo extends CloudAlertBase {
    private static final long serialVersionUID = 1L;

    /**
     * name = "alertName", value = "报警名称"
     */
    private String alertName;

    /**
     * name = "alertState", value = "报警状态"
     */
    private String alertState;

    /**
     * name = "curValue", value = "报警发生或恢复时监控项的当前值"
     */
    private String curValue;

    /**
     * name = "dimensions", value = "发生报警的对象"
     */
    private String dimensions;

    /**
     * name = "expression", value = "报警规则的表达式"
     */
    private String expression;

策略模式

策略基类

/**
 * @author wangbin16
 * @date 2024/1/18 15:41
 */
public interface CloudAlertStrategy {
    /**
     * 处理云监控告警
     * @param param
     */
    void handleCloudAlert(CloudAlertBase param);
}

阿里云策略

@Slf4j
@Service
@CloudAlertAnnotation(alertType = CloudAlertTypeEnum.ALIYUN)
public class AliyunCloudAlertStrategy implements CloudAlertStrategy {
    @Override
    public void handleCloudAlert(CloudAlertBase param) {
        // TODO 处理阿里云监控告警

        // 暂时先发送给我 @wangbin16
        SendMsgUtils sendMsgUtils = new SendMsgUtils();
        sendMsgUtils.sendP2pPopoMsg(JSON.toJSONString(param), "wangbin16@xxx", "【阿里云监控告警】");
    }
}

策略注册
import org.reflections.Reflections;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author wangbin16
 * @date 2024/1/18 15:50
 */
public class AnnotationCloudAlertStrategyFactory {
    /**
     * 存储策略
     */
    static Map<Integer, CloudAlertStrategy> strategyMap = new HashMap<>();

    static {
        registerStrategy();
    }

    /**
     * 自动注册策略
     */
    private static void registerStrategy() {
        // 通过反射获取所有的策略类
        Reflections reflections = new Reflections(CloudAlertStrategy.class.getPackage().getName());
        Set<Class<? extends CloudAlertStrategy>> cloudStrategyClassSet = reflections.getSubTypesOf(CloudAlertStrategy.class);
        if (cloudStrategyClassSet != null) {
            for (Class<?> clazz : cloudStrategyClassSet) {
                // 找到类型注解,自动完成策略注册
                if (clazz.isAnnotationPresent(CloudAlertAnnotation.class)) {
                    CloudAlertAnnotation alertTypeAnnotation = clazz.getAnnotation(CloudAlertAnnotation.class);
                    CloudAlertTypeEnum chargeType = alertTypeAnnotation.alertType();
                    try {
                        strategyMap.put(chargeType.getCode(), (CloudAlertStrategy) clazz.newInstance());
                    } catch (InstantiationException | IllegalAccessException e) {
                        e.getStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 提供注册策略接口,外部只需要调用此接口接口新增策略
     * 策略定义时,即注入,这是口子
     */
    public static void registerChargeStrategy(CloudAlertTypeEnum alertType, CloudAlertStrategy strategy) {
        strategyMap.put(alertType.getCode(), strategy);
    }
}

策略选择器

@Service
@Slf4j
public class CloudAlertStrategySelector {
    public CloudAlertStrategy selector(Integer alertType) {
        if (alertType == null) {
            return null;
        }
        return AnnotationCloudAlertStrategyFactory.strategyMap.get(alertType);
    }
}

服务调用

@Slf4j
@Service("cloudMonitorService")
public class CloudMonitorService {
    @Autowired
    private CloudAlertStrategySelector cloudAlertStrategySelector;
    public void handleCloudMonitor(CloudAlertBase param) {
        logger.info("handleCloudMonitor param:{}", JSON.toJSONString(param));
        CloudAlertStrategy selector = cloudAlertStrategySelector.selector(param.getAlertType());
        if (selector != null) {
            selector.handleCloudAlert(param);
        } else {
            logger.error("外部云告警异常调用, param:{}", JSON.toJSONString(param));
        }
    }
}

测试

调用指定的接口,执行指定的逻辑
策略模式在工作中的运用,策略模式,开发语言文章来源地址https://www.toymoban.com/news/detail-804345.html

到了这里,关于策略模式在工作中的运用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

            状态模式 (State Pattern)是一种行为型设计模式,用于解决对象在不同状态下的行为问题。它允许一个对象在其内部状态改变时改变它的行为。状态模式主要包含三个部分: 上下文 (Context)、 状态接口 (State)和 具体状态实现类 (ConcreteState)。 状态接口(St

    2023年04月14日
    浏览(42)
  • 策略模式--在SpringBoot中的使用

    策略模式主要分为三部分: 抽象策略类AbstractStrategy:负责定义抽象方法,具体策略类的继承 具体策略类ContentStrategy:负责策略类的具体实现 上下文类:ContextStrategy:负责上游模块的调用。包含一个策略属性,一个调用方法 可以有多个具体策略类 SpringBoot中,我们的具体策略

    2024年02月01日
    浏览(33)
  • 命令设计模式(Command Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

            命令设计模式 (Command Pattern)是一种行为设计模式,它将请求的操作封装为一个对象,从而实现请求者和执行者之间的解耦。这样,请求者只需要知道如何发送请求,而无需关心请求的具体执行过程。命令模式在很多场景下都非常有用,例如撤销操作、延迟执行、

    2024年02月01日
    浏览(47)
  • Unity常用设计模式-策略模式:游戏中的智慧选择

    一、什么是策略模式?        策略模式是一种行为设计模式,它定义了一系列算法,并使得这些算法可以相互替换,而使得使用算法的客户端代码不受影响。在策略模式中,算法被封装成独立的类,使得它们可以独立于客户端而变化。这种模式提供了一种简单而强大的方法

    2024年02月20日
    浏览(40)
  • 策略模式在AIBOT项目中的实际应用

    原文链接 https://www.jylt.cc/#/detail?activityIndex=2id=8d1912358fa1c1d8db1b44e2d1042b70 AIBOT 你想 我来做 AIBOT https://chat.jylt.top/ 定义 策略模式(Strategy Pattern:Define a family of algorithms,encapsulate each one,and make them interchangeable.)中文解释为:定义一组算法,然后将这些算法封装起来,以便它们之间

    2024年01月21日
    浏览(55)
  • 观察者设计模式(Observer Design Pattern)[论点:概念、组成角色、相关图示、示例代码、框架中的运用、适用场景]

            观察者设计模式(Observer Design Pattern)是一种行为型设计模式,它定义了一种对象间的一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生改变时,通知所有观察者对象,使它们能够自动更新。 主题(Subject):主题是一个抽象类或

    2023年04月24日
    浏览(45)
  • 【谈一谈】: 我们工作中的单例模式有哪些写法?

    我们要实现一个单例,首先最重要的是什么? 当然是把构造函数私有化,变成 private 类型,(为啥? 单例单例,如果谁都能通过构造函数创建对象,还叫单例吗?是不~) 嗯~我们构造函数私有化后,我们应该 操作啥 呢? 接着我们需要提供 一个方法 ,这个方法要保证初始化 有且仅 初始化 一

    2024年02月21日
    浏览(45)
  • 人工智能在信息系统安全中的运用(3),美团网络安全开发工程师岗位职能要求

    图.上下文分析 由于编纂什么行为可以是“正常”的行为是很复杂的,因此 ML (机器学习)模型通过查看历史活动和在对等组中进行比较来为每个用户构建基线。它是如何工作的?在检测到任何异常事件的情况下,评分机制聚集它们以为每个用户提供组合的风险得分。 具有较

    2024年04月14日
    浏览(52)
  • 策略模式,一种广泛应用于各种情况的设计模式(设计模式与开发实践 P5)

    定义:定义一系列算法,把它们一个个封装起来,并且可以互相替换 例如,我们要计算年终奖,年终奖根据绩效 A、B、C 来计算最终数值 最初我们很容易想到用 分支 if 来解决这个问题,如果绩效 = A 则工资 x 2,如果绩效 = B 则工资 x 3 如果经常使用这样的分支结构,你会发现

    2024年02月07日
    浏览(42)
  • 本地安全策略的运用和详解

    作者:柒烨带你飞 格言:生活的情况越艰难,我越感到自己更坚强;我这个人走得很慢,但我从不后退。   文章目录 一,本地安全策略 1.  概念 2.  打开方式 二,账户策略 1.  密码策略 2.  账户锁定策略 三,本地策略策略 1.  审核策略 2.  用户权限分配 3.  安全选项 对登

    2024年02月05日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包