2011年06月16日

GAE/PでAspyctを使ってAOP(アスペクト指向プログラミング)

ある処理の前後に本来のビジネスロジックとは関係ない処理を挟みたいことはよくある話である。
そこで今回はGAE for Pythonでアスペクト指向プログラミング(AOP)する方法を紹介する。

まずAspyctというAOP用のサードパーティ製外部モジュールをダウンロードする。ちなみに今回は Aspyct-3.0_beta_4 というバージョンをダウンロードした。こいつを解凍すると aspyct というフォルダがあるのでGAEアプリのプロジェクトフォルダへフォルダごとコピーする。
これで下準備はOK。

早速コードを書いてみよう。
以下のサンプルは、計算機クラスの足し算処理に割り込んで、勝手に引数を10倍してくれる迷惑なアプリだ。

まずは割り込むクラスから書いてみよう。
MyAspect.py
# -*- coding: utf-8 -*-
import cgi
import os

import logging
from Aspyct.aop import *

class MyAspect(Aspect):
def atCall(self, cd):
logging.info('atCall:' + str(cd.args))
#
# 二つの引数を勝手にx10してみる。
#
cd.change() # 編集不可な引数cd(tuple)を編集可に。
p1 = cd.args[0] * 10
p2 = cd.args[1] * 10
return (p1, p2), {}

def atReturn(self, cd):
logging.info('atReturn:' + str(cd.returned))

def atRaise(self, cd):
logging.info('Exception raised!')

上記のソースで大切なのは cd.change() だ。これを呼び出すことで、tupleである引数cdが編集可能となる。これをやらないと引数を変更できないので注意。そして最後の return (p1, p2), {} で、書き換えた二つの引数を返している。

次にお馴染みのhelloworld.pyだ。
helloworld.py
# -*- coding: utf-8 -*-
import cgi
import os

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
import logging
import MyAspect
from Aspyct.aop import *

#
# 計算機クラス
#
class Calc(object):
@MyAspect.MyAspect()
def add(self, p1, p2):
return p1 + p2

class MainPage(webapp.RequestHandler):
def get(self):
logging.info("MainPage#get")
calc = Calc()
ans = calc.add(1, 2) # 1+2=3 な筈が、、、
logging.info("Ans:%s" % ans) # 10+20=30になっている。

template_values = {}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))

application = webapp.WSGIApplication([('/', MainPage)], debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()


大切なのは以下の処理。
from Aspyct.aop import *

@MyAspect.MyAspect()
def add(self, p1, p2):

先頭でAspyctをインポートし、処理を差し込みたいメソッドの頭にJavaで言うところのアノテーションである @MyAspect.MyAspect() を記述している。これは MyApsect.py ファイルの中の MyAspect クラスを差し込みますよ、という宣言だ。

index.html は適当でいいので今回は省略。

さて、これを実行すると以下のようにログが出力される。
INFO 2011-06-16 00:46:46,763 helloworld.py:20] MainPage#get
INFO 2011-06-16 00:46:46,765 MyAspect.py:10] atCall:(1, 2)
INFO 2011-06-16 00:46:46,766 MyAspect.py:20] atReturn:30
INFO 2011-06-16 00:46:46,767 helloworld.py:23] Ans:30


Calc#add の処理の前後に MyAspect の処理が割り込んでいるのが分かるだろう。

このように、Javaでお馴染みのAOPをPythonでも実現でき、汎用性の高いコードを書くことが出来るようになるのだ。

ここはひとつポチっとよろしく。
人気ブログランキングへ

プログラミング Google App Engine
Dan Sanderson
オライリージャパン
売り上げランキング: 40082



posted by 寄り道退屈男 at 10:19 | Comment(0) | TrackBack(0) | GAE for Python
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/46059583
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック