アスペクト指向とは何か。Wikipediaを抜粋すると以下だ。
アスペクト指向プログラミング(アスペクトしこうプログラミング、Aspect Oriented Programming、AOP)は、オブジェクト指向ではうまく分離できない特徴(クラス間を横断 (cross-cutting) するような機能)を「アスペクト」とみなし、アスペクト記述言語をもちいて分離して記述することでプログラムに柔軟性をもたせようとする試み。
個人な感想を言えば、処理が追えなくなるんじゃないの?という感想。
以下の記事も読んだ。
アスペクト指向プログラミング入門 http://postd.cc/intro-to-aop/
prototypeを使う頻度はめっきり減ったのは別として、はじめのPhoneクラスからあまりにひどいコードがでてきてちょっとビビる。
dialにlogなんて入れた瞬間に単体テストしづらくなるだけだろうに。この例だと依存がひどいだけで、単に処理を分散させて見づらくしただけに見える。
まあ、本筋ではないのでまとめると、どうやらAOPはある処理に対して前処理や後処理を後から機能を追加できるものと捉えれば良さそうだ。(ひどくいびつな捉え方であると言えるが、やっていることは似たようなものだ)
以下の記事も読んだ。
それにしても古い記事か飛ばし記事しかでないので、流行らなかったんだなという印象を受ける。
アスペクト指向プログラミングに関する十の神話
http://prg.is.titech.ac.jp/members/masuhara/papers/aop-myth.pdf
ここにある名前ベースの技術という指摘は尤もだと思う。
"ログを取るための技術だ"。たしかに、いくつか例も出てるが確かにログ以外に実際の利用は難しく思える。
以下の記事は、アスペクトまわりの用語がよくまとまっていてよかった。
時代が来るかも?アスペクト指向プログラミング, AspectJ言語とは何か - Qiita
やはり、例がログだった。
ここまで見てきて思ったのが、基本的に静的型付けのための技術であるように思える。
動的言語なら、特定のメソッドの前後に処理を追加なんて数行でできるからだ。
JSで前処理と後処理を追加する例を書いてみる。
はじめに単純にhelloを出力するメソッドhelloを用意する。
もうprototypeなんて書く機会があまりないけど、上記のコードに倣ってちょっとes5で書いてみる。
var A = function() {}
A.prototype.hello = function() {
console.log('A: hello')
}
var a = new A()
a.hello()
// => A: hello
さて、このA: hello
前後に処理を追加したい。
例なのでbofore
とafter
を出力する。
以下の関数を用意する。
jsは第1級関数がサポートされてるので、単に関数をコピーして、前後に処理を挟んでやればいい。
function injectBeforeAfter(name, func) {
if (func.prototype[name]) {
var fn = func.prototype[name]
func.prototype[name] = function() {
console.log('before')
fn.apply(func, arguments)
console.log('after\n')
}
}
}
あとは、クラスA
を渡せばhello
の呼び出しの前後に処理を注入できる。
var injectHello = injectBeforeAfter.bind(null, 'hello')
injectHello(A)
var a = new A()
a.hello()
//=> before
//=> A: hello
//=> after
引数も渡せる。
var B = function() {}
B.prototype.hello = function(user) {
console.log('B: hello', user)
}
injectHello(B)
b.hello('山田')
//=> before
//=> B: hello 山田
//=> after
結局のところ、名前ベースであるところが一番ネックだなと思った。
この記事含めて2時間ぐらいしか調査してないので、何か間違いがあったらコメントまでお願いします。