策略模式

策略模式

定義:定義一系列的算法罐寨,把他們一個個封裝起來,并且使他們可以相互替換

看一個例子(取自 js 設計模式與開發(fā)實踐)

例如序矩,績效為 S 的人年終獎是 4 倍工資鸯绿,績效為 A 的人年終獎是 3 倍工資,績效為 B 的人年終獎是 2 倍工資
看一段代碼

var bonus = function (level, salary) {
  if (level === "S") {
    return salary * 4;
  }
  if (level === "A") {
    return salary * 3;
  }
  if (level === "B") {
    return salary * 2;
  }
};
bonus("S", 1000);

這段代碼的問題在哪里簸淀,有很多的 if,函數(shù)缺乏彈性楞慈,如果再添加一種績效,則需要深入函數(shù)內(nèi)部啃擦,修改函數(shù)囊蓝,所以我們看看使用策略模式后代碼

var strategies = {
  S: function (salary) {
    return salary * 4;
  },
  A: function (salary) {
    return salary * 3;
  },
  B: function (salary) {
    return salary * 2;
  },
};
var calculateBonus = function (level, salary) {
  return strategies[level](salary);
};

console.log(calculateBonus("S", 20000)); // 輸出:80000
console.log(calculateBonus("A", 10000)); // 輸出:30000

這樣算法的使用和算法的實現(xiàn)就分離開了,相互不再影響

代碼看著很簡單令蛉,能否想到用策略模式來優(yōu)化代碼聚霜,以及實現(xiàn),我想這需要一定的積累才能達到珠叔。

再看一個例子加強一下(取自 js 設計模式與開發(fā)實踐)
表單校驗

<html>
  <body>
    <form action="http:// xxx.com/register" id="registerForm" method="post">
      請輸入用戶名:<input type="text" name="userName" /> 請輸入密碼:<input
        type="text"
        name="password"
      />

      請輸入手機號碼:<input type="text" name="phoneNumber" />
      <button>提交</button>
    </form>
    <script>
      var registerForm = document.getElementById("registerForm");
      registerForm.onsubmit = function () {
        if (registerForm.userName.value === "") {
          alert("用戶名不能為空");
          return false;
        }
        if (registerForm.password.value.length < 6) {
          alert("密碼長度不能少于6 位");
          return false;
        }
        if (!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)) {
          alert("手機號碼格式不正確");
          return false;
        }
      };
    </script>
  </body>
</html>

沒有使用策略設計模式蝎宇,代碼中依然存在很多的 if (這給我們一個提示,如果我們寫的代碼含有大量的 if else 那么我們是不是可以用策略模式來優(yōu)化我們的代碼呢祷安?姥芥,也許以后我們遇到的時候可以停下來思考一下是否可以優(yōu)化)

使用策略模式后的代碼

<html>
  <body>
    <form action="http:// xxx.com/register" id="registerForm" method="post">
      請輸入用戶名:<input type="text" name="userName" /> 請輸入密碼:<input
        type="text"
        name="password"
      />

      請輸入手機號碼:<input type="text" name="phoneNumber" />
      <button>提交</button>
    </form>
    <script>
      /***********************策略對象**************************/
      var strategies = {
        isNonEmpty: function (value, errorMsg) {
          if (value === "") {
            return errorMsg;
          }
        },
        minLength: function (value, length, errorMsg) {
          if (value.length < length) {
            return errorMsg;
          }
        },
        isMobile: function (value, errorMsg) {
          if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
            return errorMsg;
          }
        },
      };
      /***********************Validator 類**************************/
      var Validator = function () {
        this.cache = [];
      };
      Validator.prototype.add = function (dom, rules) {
        var self = this;
        for (var i = 0, rule; (rule = rules[i++]); ) {
          (function (rule) {
            var strategyAry = rule.strategy.split(":");
            var errorMsg = rule.errorMsg;
            self.cache.push(function () {
              var strategy = strategyAry.shift();
              strategyAry.unshift(dom.value);
              strategyAry.push(errorMsg);
              return strategies[strategy].apply(dom, strategyAry);
            });
          })(rule);
        }
      };
      Validator.prototype.start = function () {
        for (var i = 0, validatorFunc; (validatorFunc = this.cache[i++]); ) {
          var errorMsg = validatorFunc();
          if (errorMsg) {
            return errorMsg;
          }
        }
      };
      /***********************客戶調(diào)用代碼**************************/
      var registerForm = document.getElementById("registerForm");
      var validataFunc = function () {
        var validator = new Validator();
        validator.add(registerForm.userName, [
          {
            strategy: "isNonEmpty",
            errorMsg: "用戶名不能為空",
          },
          {
            strategy: "minLength:6",
            errorMsg: "用戶名長度不能小于10 位",
          },
        ]);
        validator.add(registerForm.password, [
          {
            strategy: "minLength:6",
            errorMsg: "密碼長度不能小于6 位",
          },
        ]);
        var errorMsg = validator.start();
        return errorMsg;
      };
      registerForm.onsubmit = function () {
        var errorMsg = validataFunc();
        if (errorMsg) {
          alert(errorMsg);
          return false;
        }
      };
    </script>
  </body>
</html>

這段代碼,建議多閱讀幾遍汇鞭,體會一下策略模式

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凉唐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子霍骄,更是在濱河造成了極大的恐慌台囱,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件读整,死亡現(xiàn)場離奇詭異簿训,居然都是意外死亡,警方通過查閱死者的電腦和手機米间,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門强品,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屈糊,你說我怎么就攤上這事的榛。” “怎么了另玖?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵困曙,是天一觀的道長。 經(jīng)常有香客問我谦去,道長慷丽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任鳄哭,我火速辦了婚禮要糊,結果婚禮上,老公的妹妹穿的比我還像新娘妆丘。我一直安慰自己锄俄,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布勺拣。 她就那樣靜靜地躺著奶赠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪药有。 梳的紋絲不亂的頭發(fā)上毅戈,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音愤惰,去河邊找鬼苇经。 笑死,一個胖子當著我的面吹牛宦言,可吹牛的內(nèi)容都是我干的扇单。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奠旺,長吁一口氣:“原來是場噩夢啊……” “哼蜘澜!你這毒婦竟也來了?” 一聲冷哼從身側響起响疚,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤兼都,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后稽寒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扮碧,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年杏糙,在試婚紗的時候發(fā)現(xiàn)自己被綠了慎王。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡宏侍,死狀恐怖赖淤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谅河,我是刑警寧澤咱旱,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布确丢,位于F島的核電站,受9級特大地震影響吐限,放射性物質(zhì)發(fā)生泄漏鲜侥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一诸典、第九天 我趴在偏房一處隱蔽的房頂上張望描函。 院中可真熱鬧,春花似錦狐粱、人聲如沸舀寓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽互墓。三九已至,卻和暖如春蒋搜,著一層夾襖步出監(jiān)牢的瞬間轰豆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工齿诞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酸休,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓祷杈,卻偏偏與公主長得像斑司,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子但汞,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 在程序設計中宿刮,我們也常常遇到類似的情況,要實現(xiàn)某一個功能有多種方案可以選擇私蕾。比如一個壓縮文件的程序僵缺,既可以選擇zi...
    yufawu閱讀 369評論 0 3
  • 什么是策略模式? 策略模式的定義是:定義一系列的算法踩叭,把它們一個個封裝起來磕潮,并且使它們可以相互替換。 使用策略模式...
    27億光年中的小小塵埃閱讀 134評論 0 0
  • 策略模式的定義是:定義一系列的算法容贝,把它們一個個封裝起來自脯,并且使它們可以相互替換。 俗話說斤富,條條大路通羅馬膏潮。在美劇...
    梅梅_1461閱讀 421評論 0 2
  • 摘自《JavaScript設計模式與開發(fā)實踐》 在現(xiàn)實中,很多時候有多種途徑到達同一個目的地满力。比如我們要去某個地方...
    小小的白菜閱讀 283評論 0 0
  • 久違的晴天焕参,家長會轻纪。 家長大會開好到教室時,離放學已經(jīng)沒多少時間了叠纷。班主任說已經(jīng)安排了三個家長分享經(jīng)驗刻帚。 放學鈴聲...
    飄雪兒5閱讀 7,523評論 16 22