策略模式與狀態(tài)模式

狀態(tài)模式

狀態(tài)模式將狀態(tài)的切換交由具體的處理節(jié)點(diǎn)做判斷, 容器只提供執(zhí)行上下文

類模式實(shí)現(xiàn)

/**
 * 處理節(jié)點(diǎn)類
 */
abstract class State{
  state: string
  next: State
  
  constructor(state: string, next?: State){
    this.state = state
    this.next = next || this
  }
  // 狀態(tài)切換方法胳螟,交由具體的子類實(shí)現(xiàn)
  abstract change():State
}


/**
 * 狀態(tài)控制類
 */
class Store{
  // 游標(biāo), 標(biāo)記下一可調(diào)用狀態(tài)
  currentState: State
  constructor(currentState: State){
    this.currentState = currentState
  }
  run(){
    // 修改當(dāng)前游標(biāo)指向
    this.currentState = this.currentState.change()    
  }
}


/**
 * 具體的狀態(tài)節(jié)點(diǎn)類實(shí)現(xiàn)
 */
class Success extends State{
  constructor(next?: State){
    const state = 'SUCCESS'
    super(state, next)
  }
  
  // 子類實(shí)現(xiàn)具體的狀態(tài)處理
  change(): State {
    console.log(this.state)
    return this.next    
  }
}


class Fail extends State{
  constructor(next?: State){
    const state = 'Fail'
    super(state, next)
  }
  
  change(): State {
    console.log(this.state)
    return this.next
  }
}


class Loading extends State{


  success: State
  fail: State


  constructor(success?: State, fail?: State){
    const state = 'Loading'
    super(state)
    this.success = success || this
    this.fail = fail || this
  }
  
  change(): State {
    console.log(`
      ---------- LOADING ----------
    `)
    this.next = Number.parseInt(`${Math.random() * 10}`) % 2 ? this.success : this.fail
    return this.next
  }
}


function stateMod(){
  const success = new Success()
  const fail = new Fail()
  const loading = new Loading()
  const store = new Store(loading)


  success.next = loading
  fail.next = loading
  loading.success = success
  loading.fail = fail
  
  for(let i = 0; i < 10; i++){
    store.run()
  }
}


stateMod()

策略模式

調(diào)用具體執(zhí)行的函數(shù)的決策交由容器決定

類實(shí)現(xiàn)

// 決策容器
abstract class Strategy<T extends string>{
  state: T
  constructor(initState: T){
    this.state = initState
  }


  // 狀態(tài)的的切換交由的策略決策處理
  abstract strategy():void
}


type State = 'success' | 'fail' | 'loading'


class LoadData extends Strategy<State>{
  loading: Function
  success: Function
  fail: Function


  constructor(loading: Function, success: Function, fail: Function){
    super('loading')
    this.loading = loading
    this.success = success
    this.fail = fail
  }


  strategy(){
    switch (this.state) {
      case 'success':
        this.success()
        this.state = 'loading'
        break;
      case 'fail':
        this.fail()
        this.state = 'loading' 
        break;
      case 'loading':
       this.state = this.loading() ? 'success' : 'fail'
       break; 
    }
  }
}


function StrategyMod(){


  // 具體的執(zhí)行不參與狀態(tài)的切換
  const success = () => console.log('Success')
  const fail = () => console.log('Fail')
  const loading = () => {
    console.log(`
    ---------- LOADING ----------
  `)
   return Number.parseInt(`${Math.random() * 10}`) % 2
  } 


  const loadData = new LoadData(
    loading,
    success,
    fail
  )


  for(let i = 0; i < 10; i++){
    loadData.strategy()
  }
}
StrategyMod()

函數(shù)方式

interface IStrategy<T>{
  (s: T): T
}


type State = 'success' | 'fail' | 'loading'


/**
 * 值容器
 */
class Container<T>{
  state: T
  constructor(state: T){
    this.state = state
  }


  of(s: T){
    return new Container(s)
  }


  map(cb:IStrategy<T>){
    return this.of(cb(this.state))
  }
}


type Warp<T extends string> = (s: T) => Warp<T> 


function StrategyMod(){


  // 具體的執(zhí)行不參與狀態(tài)的切換
  const success = () => console.log('Success')
  const fail = () => console.log('Fail')
  const loading = () => {
    console.log(`
    ---------- LOADING ----------
  `)
   return Number.parseInt(`${Math.random() * 10}`) % 2
  } 


  // 決策函數(shù)
  const loadData = function(s: State): State{
    switch (s) {
      case 'success':
        success()
        return 'loading' 
      case 'fail':
        fail()
        return 'loading' 
      case 'loading':
        return loading() ? 'success' : 'fail' 
    }
}


  const list = new Array(10).fill('')
  list.reduce<Container<State>>((acc) => acc.map(loadData), new Container<State>('success'))
}


StrategyMod()

總結(jié)

策略模式與狀態(tài)模式,關(guān)注的是狀態(tài)切換的控制權(quán)嘉竟。

  • 策略模式由中心容器根據(jù)輸入控制具體的執(zhí)行函數(shù)舍扰,控制權(quán)在容器中
  • 狀態(tài)模式由當(dāng)前的執(zhí)行節(jié)點(diǎn)控制具體的狀態(tài)設(shè)置, 控制權(quán)在狀態(tài)節(jié)點(diǎn)中

策略模式更中心化,狀態(tài)模式更分布式陵且。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滩报,一起剝皮案震驚了整個(gè)濱河市播急,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌可训,老刑警劉巖捶枢,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烂叔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡胯努,警方通過(guò)查閱死者的電腦和手機(jī)逢防,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門忘朝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人溉箕,你說(shuō)我怎么就攤上這事≠送矗” “怎么了独郎?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贫橙。 經(jīng)常有香客問(wèn)我,道長(zhǎng)疲迂,這世上最難降的妖魔是什么莫湘? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任幅垮,我火速辦了婚禮,結(jié)果婚禮上忙芒,老公的妹妹穿的比我還像新娘呵萨。我一直安慰自己,他們只是感情好囱皿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布忱嘹。 她就那樣靜靜地躺著,像睡著了一般爹橱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慰技,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天吻商,我揣著相機(jī)與錄音艾帐,去河邊找鬼。 笑死柒爸,一個(gè)胖子當(dāng)著我的面吹牛捎稚,可吹牛的內(nèi)容都是我干的求橄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼条霜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蛔外!你這毒婦竟也來(lái)了夹厌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎光稼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體采够,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹬癌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年隅要,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了董济。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡廓啊,死狀恐怖谴轮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤唧领,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布胯杭,位于F島的核電站受啥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏居暖。R本人自食惡果不足惜藤肢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一嘁圈、第九天 我趴在偏房一處隱蔽的房頂上張望最住。 院中可真熱鬧,春花似錦涨缚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拄丰。三九已至,卻和暖如春料按,著一層夾襖步出監(jiān)牢的瞬間奄侠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工载矿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垄潮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓闷盔,卻偏偏與公主長(zhǎng)得像弯洗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逢勾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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