Teeda Extension featuring Goya 〜内部設計【AOPの適用】〜
要件定義→外部設計→(アーキテクチャ)→内部設計→コーディング→単体テスト→結合テスト
AOPの適用は、自分でも何となくやってしまっているところがあり、設計手法として改めて考えてみると、説明が難しいところがあります。
今回は、自分なりの考えをまとめてみます。
AOPをどこに適用すれば良いのか?
「AOPとは何か?」って聞かれたら答えやすいのですが、「AOPをどこに適用すれば良いのか?」と聞かれると、答えるのが難しいですね・・・。
自分で設計していても、感覚的に決めてしまっているように思います。
AOPの例として、トランザクションやロギング処理が良く取り上げられるますが、それらはシステム全体としては、どのように位置づけられるのでしょうか?
システムとして、ユーザに適用する機能(core concern)とAOPで実現する機能(crosscutting concern)は、縦横のような関連を持ちます。
そこで、トランザクションやロギングの処理を考えてみると、共通項として得られるのは、
-
- レイヤー
- 業務に依存しない共通処理
ではないかと思います。
AOPの適用箇所について、いろいろと調べて見ましたが、僕が考えるAOPの適用ポリシーでも、似たようなことが書かれていました。
Seasar2では、便利なInterceptorが標準で多く提供されている(S2AOPで用意されているInterceptor)ため、独自で作成する機会はあまりないかもしれませんが、私の場合、上のような視点で適用箇所を見出しています。
AOPに対する危惧
AOPの解説などを見ていると、「機能をあとづけできます!」という記述を良く見かけます。
しかしながら、それって、AOPを「銀の弾」扱いしすぎているように思います。
たしかに、あとづけ「も」できますよ。
ただ、AOPは、適用箇所(JointPoint)なども限られます。S2やSpringなどのDIコンテナで、確実にAOPは利用しやすくなりましたが、やはりある程度設計しておかないと、後から適用できないことがわかって、全機能を修正する必要がでてきた、なんてことに陥る可能性があります。
少なくとも、適用するレイヤーと、そこで必要となるパラメータぐらいは決めておくと良いでしょう。
大抵は、それでAOPで実現できるかどうかを判断できると思います。
Teeda Extension featuring Goya 〜内部設計〜
要件定義→外部設計→(アーキテクチャ)→内部設計→コーディング→単体テスト→結合テスト
今回から、数回に分けて内部設計について紹介していきます。
工程の位置づけ
システムがユーザに提供するものが、システム内部でどのように振舞うかを定義します。
- 各機能で、外部設計と実装を結びつけるもの(外部設計の検証にもなる)
- 機能横断的に呼び出されるもの
成果物
- UIモックアップ(更新)
- 外部設計で作成したUIモックアップに、idを追加する。
- CRUDマトリクス
- 機能毎にCRUDの処理内容をまとめる。操作シナリオとデータモデル(DB設計)の検証にもなる。
- 作成するのは手間がかかるが、試験のときのことを考えても作成しておくことをお勧めする。
- 業務ロジック設計
- 複雑な業務ロジックについて設計を行う(すべてのロジックについて行う必要はない)。主に、処理レシピとして書き出した内容が設計の対象となる。
- 共通機能設計
- Interceptor/Helper/Utilityに関する設計を行う。
設計では、どのような手法を利用しても構いません。設計/実装者が慣れた方法を取ることが良いでしょう。
共通機能を抽出する際の考え方
共通機能は、先に述べたInterceptor/Helper/Utilityに大別されます。それぞれの内容と抽出する考え方は、以下のようになります。
Interceptor
Helper
Utility
- 内容
- 機能横断的に呼び出されるが、DIする必要がないコンポーネント
- 抽出する際の考え方
- staticに呼び出すだけ
- 引数だけで戻り値が一意に決まり、状態などには因らない
- 例
- 文字列変換処理
*1:簡単な通知処理ならば、Interceptorとして実現できることもあります。条件によって送信先が変わるような場合は、Helperとして実装した方が実現しやすいでしょう