ちょっと話題の記事

JavaScriptでアスペクト指向プログラミング

2013.06.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

JavascriptでAOP

JavaではDIと同時に当たり前になったAOP(アスペクト指向プログラミング)ですが、Javascriptでも行うことができます。
今回紹介するAopJSは、JavascriptでAOPを行うためのライブラリです。
ドキュメントを参考にいろいろとためしてみましょう。

※ちなみに、AopJSは通常のライブラリとしてだけでなく、JQueryのプラグインとしても提供されています。

環境構築方法

今回使用した動作環境は以下のとおりです。

  • OS : MacOS X 10.7.5
  • Node.js : v0.10.8
  • npm : 1.2.23

gitリポジトリからAopJSを取得します。

% mkdir aopjs
% cd aopjs
% git clone https://github.com/victorcastroamigo/aopjs.git

次のようにindex.htmlを作成しましょう。次にclient.jsファイルを作成します。client.jsに処理を記述し、AopJSの動作を確認してみます。

<html>
<head>
<script src="aopjs/dist/aop-0.5.3.js"></script>
<script src="client.js"></script>
</head>
<body>
hello aop
</body>
</html>

サンプルプログラム作成

次のようにclient.jsを記述しましょう。対象となるmyFunctionをAOPオブジェクトの関数に渡し、
アドバイスであるmyAdviceをafterアドバイスとして設定します。

//client.js

//ターゲット関数
function myFunction() {
    console.log("myFunction");
}

// アドバイス
function myAdvice() {
    console.log("myAdvice");
}

// アスペクト
var proxyFunction = AOP.aspect(myFunction).after(myAdvice); 

//関数呼び出し
proxyFunction();

呼び出してみると、対象の関数が呼び出された後、アドバイスが実行されていますね。
もちろんafter以外にも、before/afterReturning/afterThrowing等のアドバイスが設定可能です。

//実行結果
myFunction
myAdvice

オブジェクトの関数にアドバイスを適用させることもできます。

var myObject = {
    myMethod: function () {
        console.log("myObject#myMethod");
    }
}
var proxyFunction2 = AOP.aspect(myObject.myMethod, myObject).before(myAdvice);
proxyFunction2();
//myObject.myMethod()とすると、アドバイスは適用されない

オブジェクトのメソッドすべてにアスペクトを適用させるケースです。
AOP.aspectがオブジェクトを受け取る場合、オブジェクトのすべてのメソッドにアドバイスが適用されます。

var myObject2 = {
    myMethod2: function () {
        console.log("myMethod2");
    },
    myOtherMethod2: function () {
        console.log("myOtherMethod2");
    }
}

function myAdvice2() {
    console.log("myAdvice2");
}

AOP.aspect(myObject2).after(myAdvice2);

myObject2.myMethod2();
myObject2.myOtherMethod2();


//実行結果
//myMethod2 
//myAdvice2 
//myOtherMethod2 
//myAdvice2

関数実行前に引数にアクセスしたり、実行後返り値にアクセスすることもできます。

//2つの引数を足して結果を返す関数の実行前/実行後にアドバイス適用
var add = AOP.aspect(function (arg1, arg2) {
    return arg1 + arg2;})
    .before(function (target, args) {
        console.log(args[0] + " + " + args[1] + " = ");
    })
    .after(function (target, args, retval) {
        console.log(retval);
    });
    
console.log("returnValue = " + add(2, 3));


//実行結果
//2 + 3 =  
//5 
//returnValue = 5

まとめ

クライアントサイドも複雑になってきているので、AOPの役立つケースもありそうですね。
簡単に使用できますし、JQueryプラグインとしても使えるので、ぜひ試してみてください。

参考サイトなど