【JavaScript】デザインパターンを知ってみる。メディエータ編

【JavaScript】デザインパターンを知ってみる。メディエータ編

今回はJavaScriptで書くメディエータパターンについて調べてみました。実践的に使っていけるパターンだと思います。Mediator は「調停者」とか「仲裁人」という意味だそうです。

なぜ使うのか?

メディエータは、いくつかのオブジェクトで情報のやり取りをしなくてはならない場合にとても有効なパターンです。メディエータパターンでは、オブジェクト同士が直接情報をやりとりするのではなく、メディエータオブジェクトを介して情報のやり取りをおこないます。

オブジェクト同士が情報のやり取りをしているイメージ

メディエータパターンのイメージ

例えば、タブ型のボタンのUIの実装を考えてみましょう。一つのタブをクリックするとアクティブになり、それまでアクティブだった他のタブがあれば、通常状態に戻る機能が必要になります。

この機能を実装するためにはどうすればよいでしょうか。
単純に考えると、全てのボタンの状態を一度リセットしてから、クリックされたボタンのみをアクティブにする方法が考えられます。例えば以下のようなコードが考えられます。

// ボタンオブジェクトを配列で管理する
var btnAry = [btnA,btnB,btnC...];

$('.btn').on('click',function(e) {
  // ボタンがクリックされたら配列のボタンに対して一度全てリセットをかける
  for(var i = 0;i < btnAry.length;i++) {
    btnAry[i].reset();
  }
  // クリックされたものだけアクティブ表示にする
  $(this).active();
});

方法として間違ってはいませんが、たった一つのアクティブな状態のボタンを探すために全てのボタンに対して処理を当てる必要があります。ボタンが3つならまだ問題はないですが、数が増えるごとにどんどん処理が複雑になってしまいます。

メディエータパターンを使う

メディエータパターンでは、状態の管理はメディエータオブジェクトにまかせてしまいます。ボタンは他のボタンの状態を気にする必要はないし、自分の状態を気にする必要もありません。自分の見た目を変える処理だけを実装すればいいのです。

// メディエータオブジェクトの実装
var Mediator =  {
  // 最後にクリックされたボタンを格納する
  last: null,
  // 最後にクリックされたボタンがあればリセット。
  // 渡されたボタンを最後にクリックされたボタンとして格納。
  register: function(target) {
    if(this.last !== null) {
      this.last.reset();
    }
    this.last = target;
  }
}

// ボタンオブジェクトの実装
function Button(target) {
  var _self = this;
  
  _self.$button = $(target);

  _self.$button.on('click',function(e) {
    // クリックされたら自分をアクティブ状態に
    _self.active();
    // メディエータに自分を通知
    Mediator.register(_self);
  });
}

// ボタンの見た目をアクティブにする処理
Button.prototype.active = function() {
  this.$button.addClass('active');
}

// ボタンの見た目をリセットする処理
Button.prototype.reset = function() {
  this.$button.removeClass('active');
}

// 初期化
$(function() {
  var $button = $('.listButton a');
  $button.each(function() {
    var btnObj = new Button(this);
  });
});

この書き方であれば、リセットの処理は最後に押された一つのボタンにだけ走ります。いくらボタンが増えても処理自体は変わりませんし、機能追加や修正があっても対応しやすくなります。

まとめ

メディエータについて調べてみました。

画面や他のオブジェクトの状態を見て動きを変えるUIはとても多いと思います。このパターンを知っておくだけですっきりと実装することができますね。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ