日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
同事的【策略模式】比我高級(jí)這么多?我哪里比不過(guò)人家?

大家好,我是林三心,用最通俗易懂的話講最難的知識(shí)點(diǎn)是我的座右銘,基礎(chǔ)是進(jìn)階的前提是我的初心~

10余年的巴里坤哈薩克網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整巴里坤哈薩克建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“巴里坤哈薩克網(wǎng)站設(shè)計(jì)”,“巴里坤哈薩克網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

最近我在項(xiàng)目中遇到一個(gè)需求,就是需要根據(jù)一個(gè)人的這些條件:

  • 名字
  • 歲數(shù)
  • 體重

根據(jù)不同的這些條件去執(zhí)行不同的函數(shù),比如:

  • 林三心-20-160: 輸出我叫林三心,我是個(gè)年輕人,我是個(gè)瘦子
  • 林三心-60-300: 輸出我叫林三心,我是個(gè)老年人,我是個(gè)胖子

這種判斷是需要嵌套判斷的,情況非常多,寫起代碼非常麻煩,且可維護(hù)性很差,所以我第一時(shí)間想到了策略模式來(lái)解決,但是發(fā)現(xiàn)大部分網(wǎng)上的策略模式方案講解都不太符合我這個(gè)需求。

最近我對(duì)策略模式又有新的理解,我想通過(guò)我自己的方式將這些知識(shí)分享給大家。

你認(rèn)識(shí)策略模式嗎?

我理解策略模式就是,在不同的條件下去做不用的事情,并且這些事情是不會(huì)互相影響的,我們可以把這些不同的事情封裝起來(lái)。

就比如下面的簡(jiǎn)單例子,根據(jù) name 的不同的值,去執(zhí)行不同的代碼:

上面的代碼怎么優(yōu)化呢?看過(guò)一些簡(jiǎn)單策略模式的朋友,肯定第一感覺(jué)就是使用對(duì)象去存儲(chǔ),其實(shí)在這個(gè)場(chǎng)景中,完全可以去這么做:

復(fù)雜情況呢?

上面的代碼例子是非常簡(jiǎn)單的,但是如果是一些比較復(fù)雜的場(chǎng)景呢?比如我不止 name 了,我加了 age ,那么這樣的 if 嵌套,你又該如何去用簡(jiǎn)單的 map 去解決呢?

有人說(shuō),那我這樣去做,不就行了~

是,其實(shí)你非要去做也能做,無(wú)非就是麻煩點(diǎn),但是如果我不止 name、age,我又加了 height、weight、username、phone 之類的判斷條件,請(qǐng)問(wèn)閣下又該如何應(yīng)對(duì)呢?而且是嵌套的哦~

還有一種情況,就是如果我們并不是每一個(gè)分支的情況都需要去執(zhí)行代碼的,比如:

  • sunshine_lin:只需要關(guān)注 20、40歲 的情況
  • sanxin_lin:只需要關(guān)注 60歲 的情況
  • 林三心:只需要關(guān)注 20歲 的情況

或者哪天我想改變規(guī)則了,比如:我想改變一下,只關(guān)注 sunshine_lin 的 40歲 情況。

在遇到上述所說(shuō)這些情況的時(shí)候,如果你還以上面的策略模式方案去解決問(wèn)題,那么解決起來(lái)會(huì)非常棘手,可維護(hù)性也不太高,所以我們應(yīng)該換一個(gè)方案~

換湯不換藥

大方向上,還是用一個(gè)對(duì)象去映射,也就是不同條件映射到不同的執(zhí)行代碼,只不過(guò)呢,這個(gè)時(shí)候我們要把條件換一換,還是剛剛的例子:

換一種思路,我們使用一個(gè)集合去當(dāng)條件,比如像這樣子:

是的,這個(gè)所謂的集合就是所有判斷條件組成的一個(gè)對(duì)象,把他轉(zhuǎn)成字符串,當(dāng)做策略的條件,這樣是不是就看起來(lái)更加方便了?但其實(shí)是有坑的,比如下面這兩種條件,其實(shí)就是同一個(gè)條件,但是因?yàn)樾蛄谢瘯r(shí)會(huì)有順序的問(wèn)題,導(dǎo)致了兩個(gè)相同的條件匹配不到同一個(gè)函數(shù):

所以我們需要對(duì)條件對(duì)象進(jìn)行排序,要保證這兩個(gè)條件匹配到同一個(gè)函數(shù),怎么做呢?我們要讓他們順序保持一直就行了??!需要利用到 Map 這個(gè)數(shù)據(jù)結(jié)構(gòu),Map 的 key 是有順序的~

這樣就保證了不同順序的條件對(duì)象,能匹配到同一個(gè)函數(shù)了~

封裝 + 可拓展性

上面的代碼都是比較散的代碼,如果想要代碼更好的復(fù)用,肯定是需要進(jìn)行封裝,使用一個(gè) class 去封裝,并且你要考慮一些邊界情況,比如:

  • 條件匹配不上,需要執(zhí)行默認(rèn)情況
  • 代碼報(bào)錯(cuò)處理

想要更好地去完成這個(gè)方案,我們可以借助另一種設(shè)計(jì)模式發(fā)布訂閱模式,具體代碼請(qǐng)看下方,我建議大家要多看代碼,多敲,從中領(lǐng)略到它到底有啥好處~

完整代碼

class Strategy {
  map = new Map();

  constructor({ defaultCbs, errorCbs }) {
    // 默認(rèn)
    this.map.set("default", defaultCbs ?? []);
    // 錯(cuò)誤
    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);
  }

  // 執(zhí)行條件情況
  do(condition) {
    const currentCondition = this.getCondition(condition);
    try {
      const cbs = this.map.get(currentCondition);
      if (cbs) {
        cbs.forEach((cb) => cb(JSON.parse(currentCondition)));
      } else {
        // 匹配不到則執(zhí)行默認(rèn)函數(shù)
        const defaultCbs = this.map.get("default");
        defaultCbs.forEach((cb) => cb(JSON.parse(currentCondition)));
      }
    } catch (e) {
      // 報(bào)錯(cuò)執(zhí)行報(bào)錯(cuò)函數(shù)
      const errorCbs = this.map.get("error");
      errorCbs.forEach((cb) => cb(e));
    }
  }
}

const strategy = new Strategy({
  defaultCbs: [
    (v) => {
      console.log("這是默認(rèn)情況", v);
    },
  ],
  errorCbs: [
    (e) => {
      console.log("這是錯(cuò)誤情況", e);
    },
  ],
});
const condition = {
  name: "sunshine_lin",
  weight: 160,
};

// 此時(shí)還沒(méi)有注冊(cè)條件事件,所以輸出默認(rèn)事件
strategy.do(condition); 

// 添加條件函數(shù)
strategy.add(condition, [
  (v) => {
    console.log("事件1", v);
  },
  (v) => {
    console.log("事件2", v);
  },
]);

// 此時(shí)有條件事件了,輸入:事件1 事件2
strategy.do(condition);

const condition2 = {
  name: "error_lin",
  weight: 1000000,
};

// 可以增加報(bào)錯(cuò)條件
strategy.add(condition2, [
  (v) => {
    throw new Error("我超重啦?。。。?);
  },
]);

// 報(bào)錯(cuò),輸出:我超重啦?。。?!
strategy.do(condition2)

網(wǎng)頁(yè)題目:同事的【策略模式】比我高級(jí)這么多?我哪里比不過(guò)人家?
文章轉(zhuǎn)載:http://m.5511xx.com/article/djdsidi.html