設計模式 Mediator

當同一個物件,之間會有頻繁交互作用時,透過中間人與參與者來進行溝通是一個很適合使用情境。 例如:多個玩家與計分板、聊天室與多名使用者。只要是需要中間一個協調者來參與都是中介者模式的好時機。

設計模式 Mediator
Photo by Dima Pima / Unsplash

筆記學習設計模式 Mediator(中介者模式)簡單的 sample code 並且紀錄一下想法。

使用情境

當同一個物件,之間會有頻繁交互作用時,透過中間人與參與者來進行溝通是一個很適合使用情境。
例如:多個玩家與計分板、聊天室與多名使用者。只要是需要中間一個協調者來參與都是中介者模式的好時機。

特點

  • 中間人
    • 統一了參與者物件的介面
    • 只需維護參與者物件的關係
    • 中央管理操作
  • 參與者
    • 被中間人統一管理
    • 每個物件都被中間人維護關係

範例

以下使用 JavaScript 當作範例,實作一個玩家與計分板的簡單概念,更新畫面這段可以有更好的呈現方式,現在這樣寫只是為了示範效果。

class Player {
  constructor(name) {
    this.point = 0
    this.name = name  
  }

  play() {
    this.point++
    mediator.played()
  }
}


const scoreboard = {
  el: document.body,
  update: function (score) {
    let msg = ''
    for (const key in score) {
      if (score.hasOwnProperty(key)) {
        msg += `${key}: ${score[key]}\n`
      }
    }
    this.el.innerHTML = msg
  }
}

class Mediator {
  constructor() {
    this.users = {}
  }

  add(player, key) {
    this.users[player.name] = {
      key: key,
      obj: player
    }
  }

  played() {
    const score = {}
    for (const userName in this.users) {
      score[userName] = this.users[userName].obj.point
    }
    scoreboard.update(score)
  }

  keypress(e) {
    for (const userName in mediator.users) {
      const user = mediator.users[userName]
      if (e.key === user.key) {
        user.obj.play()
      }
    }
  }
}

const mediator = new Mediator

mediator.add(new Player('Home'), '0')
mediator.add(new Player('Foo'), '1')
mediator.add(new Player('Bar'), '2')
window.onkeypress = function (e) {
  mediator.keypress(e)
}

player 之間的分數透過 mediator 進行溝通把分數寫在 scoreboard 上我覺得很清楚的可以感覺到這個設計模式的特點與好處,並且只需要使用 mediator.add 介面就可以加入使用者,可以在 mediator.users 內看到這個 player 的狀態,真的是清楚很多。

參考資料

https://www.dofactory.com/javascript/design-patterns/mediator