策略模式调优(多Oss存储导致代码冗余的问题)

前言

背景:本司 Oss 的服务迭代了不下 5 个了!!!!由于本司部分文件是加密存储的,且有对应的配置文件权限的面板,当切换到不同的 Oss 地址需要修改文件权限时,需要切换到对应 Oss 的 ak、sk 才能进行配置。老代码一堆的 if、else 还有各个不同的 OssUtil 着实看着难受,时不时这个 Oss 地址修改不了权限了,但是我明明已经改过了 OssUtil 啊,怎么没生效?搜一下全局变量,哦,原来 OssUtil 有不下 5 个了,我正好又是这个项目的负责人,真的操蛋,出于空闲时间,决定出手优化一下这段代码

问题背景

例如:http://oss-a、http://oss-b 是之前已经被迭代过的地址(Oss 容量已经满了),对其的修改权限、删除文件、获取加密访问地址都需用老的 Oss 的 ak、sk才能进行操作。因此老代码直接将 OssUtil 复制了 5 份出来,将里面的配置信息做了一个替换。使用的时候也很分散,有些地方用 OssUtil1、有些地方用 OssUtil2.没有做一个全局的配置,一旦涉及到切换 Oss 地址时,你就要改动多处代码,十分操蛋。

优化效果

当现有的 Oss 满了之后,迁移 Oss 地址时只需新增新的 Oss配置类即可,接口后续1亿年都不用改!!!!!做到零成本配置接入!全局统一替换的效果,后续也可以将配置放到 Nacos…中管理
在这里插入图片描述
例如:现在我有一个 beijing 的 Oss 还有一个 shangquan 的 Oss,后续如果要做替换的话。接口还是用上图那四个,我们只需新增一个策略配置类即可。
在这里插入图片描述
在这里插入图片描述

策略类的扩展

当换 Oss 存储的时候,新增如下配置类,继承我封装好的 AbstractOssStrategy 即可,然后把对应的 ak、sk、bucketName 啥的换一换,并且指定一下 Order 的优先级是第一即可。

  1. 指定优先级为第一目的:优先级第一的策略 Oss 容量没有满,负责存储解析,最新的上传文件
  2. 非优先级第一的策略类(Oss容量):负责处理解析历史文件

然后你就完成了领导布置的任务:小张,原先的 Oss 服务满了,我给你一个新的 Oss 地址,你把项目中所有用到了 Oss 的地方都给替换一下,之前的同事在这方面,可是经常犯错,一直说他改好了,可是后来 Bug 频出,我都搞不懂了,换个 Oss 地址有这么费劲吗,不过他是他,你是你,我对你还是很欣赏滴,你是个人才,勤劳肯干,并且愿意花大把的时间在检查配置文件上,好了等下我有个会要开,就先不和你说了 。我真的是欲哭无泪。
在这里插入图片描述

考虑到后续文件地址存储表过大,可能要做冷热表分离,例如:之前的用的是 OssA 服务,由于 OssA 服务满了,需要将流量迁移到 OssB 服务,但是在用 OssA 服务期间,所有的操作日志是用 OssALog 表存储的,现在 OssALog 表数据量太大,需要用 OssBLog 表存储,在配置 OssB 的策略的时候,重写 saveLog 方法即可,而 OssA 策略的 saveLog 方法里面仍然是对 OssALog 表进行操作,策略类间的逻辑互相隔离,因此提供扩展方法 saveLog 用来记录操作日志,例如:记录下载量、上传量、上传记录。但是有一个前提就是是 OssBLog 与 OssALog 表结构一样。我感觉这个功能有点鸡肋,因为限制比较多属于我自己发散出来的扩展点了。可能我自己用来了会比较顺手,开源出来就够呛了。

策略类使用

就拿 获取私有文件的访问地址 接口来说,Controller 层就几行代码(根据 url 匹配对应的策略,然后执行),看着简洁明了。线上的代码我还用了下 ApplicationListener 接口用来统一注册、管理所有的策略类。这里就不贴出来了。

    //策略工厂
    @Autowired
    private OssStrategyFactory ossStrategyFactory;

    @ApiOperation("私有文件获取加密路径")
    @PostMapping("csdnGetAclPath")
    public Result csdnGetAclPath(@RequestParam("url") String url) throws Throwable {
    //从策略工厂中根据url匹配到对应的策略,然后进行执行
        return Result.success(ossStrategyFactory
                .getSuitAbleStrategy(url)
                .getAclPath(url, 60000));
    }

当然你也可以用这种方式调用策略类,通过依赖注入的方式,将所有的实现了 OssStrategy 接口的 Oss 策略注入到一个 List 中,然后循环遍历到合适的策略执行。

@Autowired
private List<OssStrategy> ossStrategies;
/**
* 根据 url 匹配具体的策略执行
* @param url
* @return
*/
public OssStrategy getSuitAbleStrategy(String url) {
    if (StringUtils.isEmpty(url)) return ossStrategies.get(0);
    try {
        return ossStrategies
                .stream()
                .filter(ossStrategy -> {return ossStrategy.support(url);})
                .findFirst().orElseThrow(new Supplier<Throwable>() {
                    @Override
                    public Throwable get() {
                        return new RuntimeException("系统未找到合适的策略执行!");
                    }
                });
    } catch (Throwable e) {
        e.printStackTrace();
        throw new RuntimeException("系统未找到合适的策略执行!");
    }
}

总结

本文以真实业务场景为例:以如下几点展开诉说,策略模式是如何使用的

1: 编写顶级策略接口(OssStrategy)
2: 编写具体的策略实现类(OssStrategyImpl)
3: 通过 @Autowired 注入所有的策略实现类到一个 List 中,然后挨个遍历所有策略,直到找出合适的策略,然后执行
4: 后续策略类的扩展的话,新增一个顶级策略接口(OssStrategy)的实现类即可

更多关于实战中设计模式的落地应用可以扫描下方二维码,不定期更新更多干货

  1. B站账号搜用户:小咸鱼的技术窝
  2. 微信公众号搜:小咸鱼的技术窝
  3. CSDN博客搜:张子行的博客

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小咸鱼的技术窝

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值