策略模式在AIBOT项目中的实际应用

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

原文链接https://www.jylt.cc/#/detail?activityIndex=2&id=8d1912358fa1c1d8db1b44e2d1042b70AIBOT 你想 我来做AIBOThttps://chat.jylt.top/

定义

策略模式(Strategy Pattern:Define a family of algorithms,encapsulate each one,and make them interchangeable.)中文解释为:定义一组算法,然后将这些算法封装起来,以便它们之间可以互换,属于一种对象行为型模式。总的来说策略模式是一种比较简单的模式,听起来可能有点费劲,其实就是定义一组通用算法的上层接口,各个算法实现类实现该算法接口,封装模块使用类似于 Context 的概念,Context 暴漏一组接口,Context 内部接口委托到抽象算法层。

是不是每个字都能看懂,拼到一块不知所以然了。最初看到这句话时也不知道啥意思,下面有一个类图供大家看下:策略模式在AIBOT项目中的实际应用,策略模式,设计模式,java

组成角色很简单,对于新手来说,实现起来可能会毫无思路。其实主要使用的就是多态的特性。

实现

了解了基本概念之后,可能对策略模式仅仅是一个了解的状态,动手实操可能还没有什么思路。下面以我的AI项目AIBOT中图片生成功能来说一下策略模式是如何落地的。

先看一下具体的功能点:

策略模式在AIBOT项目中的实际应用,策略模式,设计模式,java

目前AI作图只有两个功能,文生图和人像重绘,如何实现这两个功能呢?

普通实现方式

最简单高效的方法是平铺直叙的写代码,通过 if-else 来区分具体是哪个功能,例如:

    @PostMapping("/genImg")
    public ResponseKit<Object> genImg(int type) {
        if (type == 1) {
            // 文生图逻辑
        } else if (type == 2) {
            // 人像重绘逻辑
        } else if (type == ...) {
            // 其他图像生成逻辑
        }
    }
优点
  • 代码实现方便,不需要做过多设计
  • 代码条理比较清晰,自上而下很容易找出来哪块逻辑实现的是什么功能
缺点
  • 会增加类的复杂性,这些逻辑虽都是图片生成,但具体实现逻辑不是同一类,都放到同一个类中,会使这个类变得大而全,与 职责单一 的设计规范相冲突
  • 如果日后需要增加其他图像生成逻辑,需要频繁的修改这个类,而这个类中又有太多其他生成规则的逻辑,修改、新增逻辑可能会对其他已有逻辑造成意料之外的影响,为了避免这种影响可能引入的错误,我们就要对受影响的逻辑都要进行回归测试。这样无形间增加了测试的工作量,与 开闭原则 设计规范相冲突
策略模式实现

依据上面的类图,我们先一步步通过策略模式来实现功能,然后来看一下策略模式有什么优缺点

首先我们需要先定义一个通用接口:

public interface GenImgStrategy {
    ResponseKit<Object> genImg();
}

接口很简单,就一个抽象方法:生成图片;然后我们定义一下 文生图 和 人像重绘 的具体实现逻辑。这两个逻辑都统一实现 GenImgStrategy 接口:

public class TextToImgStrategyImpl implemets GenImgStrategy {
    @Override
    public ResponseKit<Object> gen() {
  	// 文生图具体实现逻辑
    }
}

public class GenImgStyleStrategyImpl implemets GenImgStrategy {
    @Override
    public ResponseKit<Object> gen() {
  	// 人像重绘具体实现逻辑
    }
}

定义好了接口和实现类之后,我们如何通过 API 接口中的 type 参数来确定需要执行 文生图 的逻辑还是执行 人像重绘 的逻辑呢?这时候我们需要一个辅助类:

public class GenImgStrategyContext {

    private static final Map<Integer, GenImgStrategy> map = new HashMap<>();

    static {
	// 初始化
        map.put(1, new TextToImgStrategyImpl());
        map.put(2, new GenImgStyleStrategyImpl());
  	map.put(..., ...);
    }

    // type=1:执行文生图逻辑;type=2:执行人像重绘逻辑
    public ResponseKit<Object> doGen(Integer type) {
        GenImgStrategy genImgStrategy = map.get(type);
        if (genImgStrategy == null) {
            log.error("类型异常,type={}", type);
            return ResponseKit.error("参数异常");
        }
        return genImgStrategy.gen();
    }
}

这里使用多态的特性,在执行 doGen 方法的时候,通过 type 值来获取不同策略的具体实现类,最后执行 gen 方法的时候,其实执行的是具体实现类中的方法

API 接口只需要改为以下形式,就可以轻松调用不同的图像生成逻辑了:

    @PostMapping("/genImg")
    public ResponseKit<Object> genImg(int type) {
       GenImgStrategyContext context = new GenImgStrategyContext();
       return context.doGen(type);
    }

这样改造之后,我们就通过 策略模式 来实现了图片生成的两种实现逻辑,后续如果有新的图片生成逻辑,只需要再增加一个实现类,在 context 类的 map 中再增加一种类型即可,对现有的两种实现逻辑实现了零侵入,做功能验证的时候只需要验证新增的逻辑即可,无需担心对现有功能的其他影响。

综合以上,我们看一下策略模式的优缺点:

优点
  • 极大的提高了程序的扩展性
  • 使程序更加的 高内聚,低耦合
  • 提高了后续功能扩展的效率
缺点
  • 增加了程序的复杂性
  • 如果策略较多,会有很多的策略实现类

看到这里之后,有些小伙伴可能还是懵懵懂懂的状态,毕竟纸上得来终觉浅,需要动手实操,最好是在自己的项目中实践一下,立即会有柳暗花明又一村的感觉。

这些都是我的真实感受,我在2020年就去有意识的学习了各种设计模式,但一直没有使用场景,也就只停留在了解的层面,知道有这么个概念,直到两个月前,在团队项目中实际看到了同事使用策略模式来解决实际问题的代码,瞬间豁然开朗,原来是这么用的。然后就在图像生成的功能上使用了,好处确实很明显。

除此之外,AIBOT 中在支付功能也是用了策略模式,来实现 会员、图像、单次充值的不同场景。

总结

策略模式虽然好处多多,但技术没有银弹,合适的才是最好的。对于经常变更策略的场景,策略模式确实能够更好的选择,但是如果不加选择的使用策略模式,会不自觉陷入过度设计的陷阱文章来源地址https://www.toymoban.com/news/detail-813095.html

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

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

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

相关文章

  • 策略模式,一种广泛应用于各种情况的设计模式(设计模式与开发实践 P5)

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

    2024年02月07日
    浏览(32)
  • 【设计模式——学习笔记】23种设计模式——策略模式Strategy(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    有各种鸭子,比如野鸭、北京鸭、水鸭等。 鸭子有各种行为,比如走路、叫、飞行等。不同鸭子的行为可能略有不同。要求显示鸭子的信息 不同的鸭子继承一个父类Duck,如果是相同的行为就继承,不同行为就重写方法 实现 【鸭子抽象类】 【野鸭】 【北京鸭】 【玩具鸭】

    2024年02月12日
    浏览(46)
  • Visual C++中的虚函数和纯虚函数(以策略设计模式为例)

    我是荔园微风,作为一名在IT界整整25年的老兵,今天来说说Visual C++中的虚函数和纯虚函数。该系列帖子全部使用我本人自创的对比学习法。也就是当C++学不下去的时候,就用JAVA实现同样的代码,然后再用对比的方法把C++学会。 直接说虚函数和纯虚函数有很多人会直接晕,但

    2024年02月12日
    浏览(37)
  • Vuex在项目中的实际应用

    最近让我搞一个关怀版本的系统。纯纯前端、无语死。就是整个系统的字体还有框框啥的变大。简单暴力的做法就是重新写一套样式咯,这不纯纯累死人啊。琢磨了一下,如果可以保存关怀版的一个标志,然后全部组件都可以获取到该标志。通过该标志,然后动态的指定类的

    2024年02月03日
    浏览(43)
  • RabbitMQ在实际项目中的应用

    RabbitMQ简介 以商品订单场景为例, 如果商品服务和订单服务是两个不同的微服务,在下单的过程中订单服务需要调用商品服务进行扣库存操作。按照传统的方式,下单过程要等到调用完毕之后才能返回下单成功,如果网络产生波动等原因使得商品服务扣库存延迟或者失败,会

    2024年02月04日
    浏览(29)
  • Java 双指针项目中的实际应用

    最近在做财务相关的系统,对账单核销预付款 从技术角度来看就是将两个数组进行合并 对账单核销预付款前提条件: 对账单总金额必须等于未核销金额 对账单数据 单号 金额 B0001 100 B0002 80 B0003 120 预付款数据 单号 未核销金额 PRE001 110 PRE002 190 结果数据 预付款单号 核销金额

    2024年02月02日
    浏览(98)
  • Java 双指针在实际项目中的应用

    最近在做财务相关的系统,对账单核销预付款 从技术角度来看就是将两个数组进行合并 对账单核销预付款前提条件: 对账单总金额必须等于未核销金额 对账单数据 单号 金额 B0001 100 B0002 80 B0003 120 预付款数据 单号 未核销金额 PRE001 110 PRE002 190 结果数据 预付款单号 核销金额

    2024年02月02日
    浏览(42)
  • Spring AOP:面向切面编程在实际项目中的应用

    🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页 ——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础

    2024年02月09日
    浏览(29)
  • 前端工程中的设计模式应用

    本文旨在系统性介绍一下23种设计模式,给出通俗易懂的案例、结构图及代码示例,这也是我自身学习理解的过程。或许其中的几种设计模式写的并不是很清晰明了易懂,更详细的可根据提到的参考文献进行深入学习。 什么是设计模式 设计模式这个概念是由一本名为《设计模

    2024年02月16日
    浏览(32)
  • 【设计模式-6】建造者模式的实现与框架中的应用

     建造者模式又被成为生成器模式,是一种使用频率比较低,相对复杂的创建型模式,在很多源码框架中可以看到建造者的使用场景,稍后我们会在本文末尾展示几个框架的使用案例。  建造者模式所构造的对象通常是比较复杂而且庞大的,也是按照既定的构建顺序将对象中

    2024年02月02日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包