天天看點

政策模式與狀态模式不是雙胞胎,而是情侶!

閱讀本文大約需要 4.5 分鐘

文章經作者老姚,授權轉載

今天說說搞對象這件事情兒。

我們經常愛問一個人,你為啥還單着?

對方的回答無非是如下這兩種:

  • 沒遇到合适的。
  • 太忙了,沒有時間。

其他回答,要麼能歸于這二者其一,要麼二者兼顧。

然而,在我看來,這二者分别對應了政策模式和狀态模式。

使用背景語言的同學都知道政策模式和狀态模式是對雙胞胎,隻有出生之後才分開。

又或說二者長得十分像,但是性格迥然不同。

我認為這種說法沒有說到點子上,準确地說二者是情侶,一男一女。

1. 政策模式

那麼什麼是政策模式?

政策、政策,講究的是做一件事情可以有不同的招數。

是以很多書籍都愛用“錦囊妙計”來說它。

var doSomething1 = function() {
  console.log('xxx');
};
var doSomething2 = function() {
  console.log('yyy');
}
// 核心
var doSomething = function(strategy) {
  if (strategy == 'xxx') doSomething1();
  if (strategy == 'yyy') doSomething2();
};
doSomething('xxx'); // xxx
doSomething('yyy'); // yyy
           

複制

上面的代碼就是政策的一種

if-else

實作方式。

在前端使用可以如下實作政策模式:

var doSomething = function(strategy) {
  strategys[strategy]();
};
var strategys = {
  xxx: function() {
    console.log('xxx');
  },
  yyy: function() {
    console.log('yyy');
  }
};
doSomething('xxx'); // xxx
doSomething('yyy'); // yyy
           

複制

政策模式,你傳什麼,我就使用什麼招數!

2. 狀态模式

政策模式的分析暫告一段落,我們再來看看什麼是狀态?

狀态、狀态,今天沒心情上班,此心情就是狀态。

之前看過一個段子:

A:來了?

B:來了。

A:來了?

B:來了。

A:來嗎?

B:不來了。

這個段子的含義是,能不能“來”,取決于目前的狀态。

一個具體例子,開關,它最能展現出狀态。

var state = 'off';
var doSomething1 = function() {
  if (state == 'off') {
    console.log('doSomething1 and turn to on');
    flag = 'on';
  }
  if (state == 'on') {
    console.log('doSomething1 else');
  }
};
var doSomething2 = function() {
  if (state == 'off') {
    console.log('doSomething2');
  }
  if (state == 'on') {
    console.log('doSomething2 else and turn to off');
    flag = 'off';
  }
}

doSomething1(); // doSomething1 and turn to on
doSomething1(); // doSomething1 else
doSomething2(); // doSomething2 else and turn to off
doSomething2(); // doSomething2
           

複制

每次去做事情時,結果是取決于目前的狀态的。

上述邏輯改成狀态模式實作:

var doSomething1 = function () {
  state.doSomething1();
};
var doSomething2 = function () {
  state.doSomething2();
};
var off = {
  doSomething1: function () {
    console.log('doSomething1 and turn to on');
    state = on;
  },
  doSomething2: function () {
    console.log('doSomething2');
  }
}
var on = {
  doSomething1: function () {
    console.log('doSomething1 else');
  },
  doSomething2: function () {
    console.log('doSomething2 else and turn to off');
    state = off;
  }
}
var state = off
doSomething1(); // doSomething1 and turn to on
doSomething1(); // doSomething1 else
doSomething2(); // doSomething2 else and turn to off
doSomething2(); // doSomething2
           

複制

ok,這就是狀态指導行為。

3. 情侶關系

政策模式和狀态模式是什麼以及如何簡單實作,應該相對清楚了。

使用相應模式後,代碼變得清晰了,也容易應對變化。

可以新增不同的政策,可以新增不同的狀态。

現在我們來看看他倆為啥是情侶關系?

政策模式根據外界條件來選取不同的政策。

狀态模式根據内部狀态來決定不同的反應。

"有象斯有對,對必反其為"。

一個外,一個内。

這兩句看起來是對仗工整。但是看二者代碼,卻沒有這麼覺得呢?

發現政策模式代碼量小,而狀态模式代碼量大,後者幾乎是前者的兩倍。

說二者是男女,政策應該是男的,而狀态是女的。

男的關心的是如何快速解決問題,拿出解決方法。

女人關心的是目前心情和情緒的安撫,關注内在狀态。

從上面的代碼量來看,女生想的心事兒比較多。

下面讓例子代碼量對等一下。

這裡用政策模式來嘗試模拟你的技能和興趣。

var 絕技 = {
  思考: function () {
    console.log("胡思亂想");
  },
  看書: function() {
    console.log('一氣呵成');
  }
};

var 愛好 = {
  吹牛: function () {
    console.log("牛上天了");
  },
  抽煙: function() {
    console.log("騰雲駕霧");
  }
};

var 你 = {
  展示絕技: function(strategy) {
    絕技[strategy]();  
  },
  展示愛好: function(strategy) {
    愛好[strategy]();
  }
};

你.展示絕技("思考"); // 胡思亂想
你.展示絕技("看書"); // 一氣呵成
你.展示愛好("吹牛"); // 牛上天了
你.展示愛好("抽煙"); // 騰雲駕霧
           

複制

上述代碼封裝了兩組算法,每組算法内由外界來決定選擇具體某種算法。

那麼對于狀态模式,也來寫一下自己。

var 煩 = {
  吹牛: function() {
    console.log('吹一吹,心情大爽啊');
    目前心情 = 爽;
  },
  抽煙: function() {
    console.log('心情不好的時候,越抽越沒勁');
  }
};

var 爽 = {
  吹牛: function() {
    console.log('越吹越爽');
  },
  抽煙: function() {
    console.log('一想起吸煙有害健康,開始不爽起來');
    目前心情 = 煩;
  }
};

var 目前心情 = 煩;

var 老姚 = {
  吹牛: function() {
    目前心情["吹牛"]();
  },
  抽煙: function() {
    目前心情["抽煙"]();
  }
};
老姚.吹牛(); // 吹一吹,心情大爽啊
老姚.吹牛(); // 越吹越爽
老姚.抽煙(); // 一想起吸煙有害健康,開始不爽起來
老姚.抽煙(); // 心情不好的時候,越抽越沒勁
           

複制

狀态模式是封裝一個個狀态,狀态封裝所有行為,具體某個行為,由目前的狀态來決定。

現在代碼量等同了。有看出了一種對偶關系了嗎?

政策模式:定義了一系列的算法,并将每一個算法封裝起來,而且使它們還可以互相替換。政策模式讓算法獨立于使用它的客戶而獨立變化。

狀态模式:允許一個對象在其内部狀态改變時改變它的行為。對象看起來似乎修改了它的類。

二者定義裡,都有“不同”這個詞語。

有象斯有對,對必反其為。

政策模式取決于傳進來的政策。

狀态取決于上一次調用後,目前的狀态。

但是,政策模式好了解。也很好應用。宛如一個少年,沒啥心思。

狀态模式,我覺得就比較屌了。

對于一個複雜的過程,狀态模式才能發揮真正實力。

關鍵你如何去劃分狀态,構造出狀态機。

看來女人不隻是半邊天那麼簡單。

對于狀态模式的使用,讓我想起一個故事。

說是有一位精神病人,跑到屋裡,把門從裡面反鎖。

然後大聲對屋外喊着,我要把你們鎖進裡面,永遠都别想出去!!

不知道我有沒有說清楚,希望有所幫助。

也歡迎閱讀老姚的《JS正則迷你書》。https://github.com/qdlaoyao/js-regex-mini-book

推薦閱讀

我的公衆号能帶來什麼價值?(文末有送書規則,一定要看)

每個前端工程師都應該了解的圖檔知識(長文建議收藏)

為什麼現在面試總是面試造火箭?