当前位置:首页 > 科技  > 软件

同事的【策略模式】比我高级这么多?我哪里比不过人家?

来源: 责编: 时间:2024-01-22 17:24:14 309观看
导读大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~最近我在项目中遇到一个需求,就是需要根据一个人的这些条件:名字岁数体重根据不同的这些条件去执行不同的函数,比如:林三心-20-1

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~BKj28资讯网——每日最新资讯28at.com

最近我在项目中遇到一个需求,就是需要根据一个人的这些条件:BKj28资讯网——每日最新资讯28at.com

  • 名字
  • 岁数
  • 体重

根据不同的这些条件去执行不同的函数,比如:BKj28资讯网——每日最新资讯28at.com

  • 林三心-20-160: 输出我叫林三心,我是个年轻人,我是个瘦子
  • 林三心-60-300: 输出我叫林三心,我是个老年人,我是个胖子

这种判断是需要嵌套判断的,情况非常多,写起代码非常麻烦,且可维护性很差,所以我第一时间想到了策略模式来解决,但是发现大部分网上的策略模式方案讲解都不太符合我这个需求。BKj28资讯网——每日最新资讯28at.com

最近我对策略模式又有新的理解,我想通过我自己的方式将这些知识分享给大家。BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

你认识策略模式吗?

我理解策略模式就是,在不同的条件下去做不用的事情,并且这些事情是不会互相影响的,我们可以把这些不同的事情封装起来。BKj28资讯网——每日最新资讯28at.com

就比如下面的简单例子,根据 name 的不同的值,去执行不同的代码:BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

上面的代码怎么优化呢?看过一些简单策略模式的朋友,肯定第一感觉就是使用对象去存储,其实在这个场景中,完全可以去这么做:BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

复杂情况呢?

上面的代码例子是非常简单的,但是如果是一些比较复杂的场景呢?比如我不止 name 了,我加了 age ,那么这样的 if 嵌套,你又该如何去用简单的 map 去解决呢?BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

有人说,那我这样去做,不就行了~BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

是,其实你非要去做也能做,无非就是麻烦点,但是如果我不止 name、age,我又加了 height、weight、username、phone 之类的判断条件,请问阁下又该如何应对呢?而且是嵌套的哦~BKj28资讯网——每日最新资讯28at.com

还有一种情况,就是如果我们并不是每一个分支的情况都需要去执行代码的,比如:BKj28资讯网——每日最新资讯28at.com

  • sunshine_lin:只需要关注 20、40岁 的情况
  • sanxin_lin:只需要关注 60岁 的情况
  • 林三心:只需要关注 20岁 的情况

或者哪天我想改变规则了,比如:我想改变一下,只关注 sunshine_lin 的 40岁 情况。BKj28资讯网——每日最新资讯28at.com

在遇到上述所说这些情况的时候,如果你还以上面的策略模式方案去解决问题,那么解决起来会非常棘手,可维护性也不太高,所以我们应该换一个方案~BKj28资讯网——每日最新资讯28at.com

换汤不换药

大方向上,还是用一个对象去映射,也就是不同条件映射到不同的执行代码,只不过呢,这个时候我们要把条件换一换,还是刚刚的例子:BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

换一种思路,我们使用一个集合去当条件,比如像这样子:BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

是的,这个所谓的集合就是所有判断条件组成的一个对象,把他转成字符串,当做策略的条件,这样是不是就看起来更加方便了?但其实是有坑的,比如下面这两种条件,其实就是同一个条件,但是因为序列化时会有顺序的问题,导致了两个相同的条件匹配不到同一个函数:BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

所以我们需要对条件对象进行排序,要保证这两个条件匹配到同一个函数,怎么做呢?我们要让他们顺序保持一直就行了!!需要利用到 Map 这个数据结构,Map 的 key 是有顺序的~BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

这样就保证了不同顺序的条件对象,能匹配到同一个函数了~BKj28资讯网——每日最新资讯28at.com

封装 + 可拓展性

上面的代码都是比较散的代码,如果想要代码更好的复用,肯定是需要进行封装,使用一个 class 去封装,并且你要考虑一些边界情况,比如:BKj28资讯网——每日最新资讯28at.com

  • 条件匹配不上,需要执行默认情况
  • 代码报错处理

想要更好地去完成这个方案,我们可以借助另一种设计模式发布订阅模式,具体代码请看下方,我建议大家要多看代码,多敲,从中领略到它到底有啥好处~BKj28资讯网——每日最新资讯28at.com

BKj28资讯网——每日最新资讯28at.com

完整代码

class Strategy {  map = new Map();  constructor({ defaultCbs, errorCbs }) {    // 默认    this.map.set("default", defaultCbs ?? []);    // 错误    this.map.set("error", errorCbs ?? []);  }  // 获取条件key  getCondition(condition) {    const conditionMap = new Map();    Object.keys(condition)      .sort()      .forEach((key) => {        conditionMap.set(key, condition[key]);      });    return JSON.stringify(Object.fromEntries(conditionMap));  }  // 增加条件情况  add(condition, conditionCbs) {    const currentCondition = this.getCondition(condition);    let cbs = this.map.get(currentCondition);    if (!cbs) {      this.map.set(currentCondition, []);      cbs = this.map.get(currentCondition);    }    cbs.push(...conditionCbs);  }  // 执行条件情况  do(condition) {    const currentCondition = this.getCondition(condition);    try {      const cbs = this.map.get(currentCondition);      if (cbs) {        cbs.forEach((cb) => cb(JSON.parse(currentCondition)));      } else {        // 匹配不到则执行默认函数        const defaultCbs = this.map.get("default");        defaultCbs.forEach((cb) => cb(JSON.parse(currentCondition)));      }    } catch (e) {      // 报错执行报错函数      const errorCbs = this.map.get("error");      errorCbs.forEach((cb) => cb(e));    }  }}const strategy = new Strategy({  defaultCbs: [    (v) => {      console.log("这是默认情况", v);    },  ],  errorCbs: [    (e) => {      console.log("这是错误情况", e);    },  ],});const condition = {  name: "sunshine_lin",  weight: 160,};// 此时还没有注册条件事件,所以输出默认事件strategy.do(condition); // 添加条件函数strategy.add(condition, [  (v) => {    console.log("事件1", v);  },  (v) => {    console.log("事件2", v);  },]);// 此时有条件事件了,输入:事件1 事件2strategy.do(condition);const condition2 = {  name: "error_lin",  weight: 1000000,};// 可以增加报错条件strategy.add(condition2, [  (v) => {    throw new Error("我超重啦!!!!");  },]);// 报错,输出:我超重啦!!!!strategy.do(condition2)

本文链接:http://www.28at.com/showinfo-26-66194-0.html同事的【策略模式】比我高级这么多?我哪里比不过人家?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python中zoneinfo模块的用法

下一篇: C++内存管理的奥秘:从基础到高级

标签:
  • 热门焦点
  • 5月安卓手机好评榜:魅族20 Pro夺冠

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年5月1日至5月31日,仅限国内市场。第一名:魅族20 Pro好评率:97.50%不得不感慨魅族老品牌还
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 如何正确使用:Has和:Nth-Last-Child

    我们可以用CSS检查,以了解一组元素的数量是否小于或等于一个数字。例如,一个拥有三个或更多子项的grid。你可能会想,为什么需要这样做呢?在某些情况下,一个组件或一个布局可能会
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • 谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌在KDD 2023发表了一篇工作,探索了推荐系统ranking模型的训练稳定性问题,分析了造成训练稳定性存在问题的潜在原因,以及现有的一些提升模型稳定性方法的不足,并提出了一种新
  • 慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz“难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?”这一番话,出自百合网联合创
  • 自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 华为Mate 60保护壳曝光:硕大后置相机模组 凸起程度有惊喜

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
Top