インターセプタでコマンド実行条件をチェック
インターセプタの使い方その1。インターセプタを使って、コマンドの実行条件チェックを行います。
何がうれしいか。
- 透過的なチェック機能の追加
- 個別のコマンドの実行前にちまちまチェックとかいれるのは、実装漏れの元。すべてのコマンドに一括で適用したい。ここでインターセプタを使うのです。
- チェック条件の集中管理
- コントローラのAPIに個別にチェック条件を書いているとチェック条件が散在しがちです。インターセプタを使うと、これらを一箇所で集中管理出きます。
サンプル
- コントローラーとして KittenServiceを定義。
- KittenServiceの各APIの実行条件をインターセプタで定義。
- applyInterceptor()でコントローラーに適用する。(applyInterceptor()は昨日作ったものです。)
var stdout = document.getElementById("stdout"); /** * インターセプターを適用する。 * @param {Object} target 適用対象のオブジェクト * @param {Regex} regex 適用する関数名の正規表現 * @param {Function} interceptor 適用するインターセプター */ function applyInterceptor( target, regex, interceptor ) { for ( var f in target ) { if ( typeof target[f] == "function" && regex.test( f ) ) { (function() { // f をローカル化するため関数で。 var x = f; var original = target[x]; target[x] = function( ) { // インターセプターを実行する関数に置き換える。 return interceptor( x, target, original, arguments ); } })(); } } } /** コントローラー */ function KittenService( ) { this.state = "stop"; } KittenService.prototype = { meow: function() { stdout.innerHTML += "meow!<br/>"; }, run: function() { this.state = "running"; stdout.innerHTML += "running..<br/>"; }, stop: function() { this.state = "stop" ; stdout.innerHTML += "stopped.<br/>"; }, jump: function() { stdout.innerHTML += "jump!<br/>"; } } // コントローラーを作成。 var service = new KittenService(); // 条件チェックインターセプターを適用。 applyInterceptor( service, /^.*$/, function( f, target, original, arguments ) { // 各処理が実行可能かチェック。 var enable = true; if ( target.state == "running" ) { // 走っている間は、さらに走ったり、鳴いたりできない。 if ( f == "run" || f == "meow" ) { enable = false; } } else { // 止まっている間は、止まれない。 if ( f == "stop" ) { enable = false; } } if ( enable ) { return original.apply( target, arguments ); } else { // 実行できない場合、メッセージを表示しコントローラのAPIは実行しない。 window.alert("実行できません!"); } } );