アスペクト指向の基礎とさまざまな実装:アスペクト指向のバリエーション解説(1)
2年ほど前から耳にするようになった「アスペクト指向」も最近ようやく広まってきた。この連載では「アスペクト指向とは何か?」というところから始め、AspectJやJBossAOPなどを用いたAOPの実装を紹介していく。
関心事の分離とは?
アスペクト指向の話には必ずといっていいほど「SOC」という言葉が登場する。このSOCは「Separation Of Concerns」の略であり、一般的には「関心事の分離」と訳されている。アスペクト指向を理解するためには「SOC」の概念を理解することが重要である。ここで、「また新しい3文字略語か」と顔をしかめて記事を読むのをやめてしまう読者がおられるかもしれないが、少し待ってほしい。このSOCは決して新しいキーワードなどではない。SOCとは、1960年代から1970年代にかけてのソフトウェア工学の黎明(れいめい)期に活躍し、「構造化プログラミング」を提唱したことでも有名なダイクストラによって産声を上げた言葉なのである(注1)。
ここでいう「関心事」とは、ソフトウェアを構成するさまざまな要素のうち「個別に着目することができ」なおかつ「ひとまとめに扱うことのできる」 “何か”と定義することができる。そして、ソフトウェアの中心的な本体からさまざまな関心事を分離することで、保守性や再利用性が高まると考えられるのである。
ダイクストラはプログラミングの処理フローにおける副次処理や共通処理を「サブルーチン」という関心事として、メインとなる処理フローから分離するプログラミングの必要性を説いた。これによって、プログラムの保守性や再利用性は向上したが、このレベルの「関心事の分離」では、「処理(手続き)」という関心事を分離しただけにすぎず、「データ」という関心事は完全に分離することができていない。あるいはC言語の「構造体」などは、反対にデータという関心事だけを分離するための仕組みとして提供されているものであり、手続きを一体化することはできない。
そこで登場するのが「オブジェクト指向」である。オブジェクト指向では「関連するデータ」と「処理手続き」の両方を「クラス」という形式の関心事として分離することに成功した。オブジェクト指向によって「関心事の分離」はより進んだ形でソフトウェアに適用されることとなり、保守性や再利用性が高いレベルで実現されるようになったことは事実である。しかしながらオブジェクト指向をもってしても、まだ「関心事の分離」が不完全であり、その不完全さを克服するために「アスペクト指向」と「AOP」が研究されることになる。
アスペクト指向と AOP
読者の中には「○○指向」という言葉に拒絶反応を示してしまう方もいらっしゃることだろう。「指向」という言葉を筆頭に、その周辺にはとかく難解なイメージの言葉がはんらんしていることも確かである。「アスペクト指向」もまた難解なイメージを与えてしまう言葉のようだが、アスペクト指向は決して複雑怪奇な概念や理論ではない。むしろその目指すところは至ってシンプルである。アスペクトは「様相」「側面」「視点」といった言葉に訳されているが、要するにソフトウェアのさまざまな「様相」や「側面」に注目するパラダイムがアスペクト指向なのである(注2)。
では、具体的に「様相」や「側面」とは何か? 筆者はこれらを「関心事」と同じようなものであるととらえている。アスペクト指向は「Advanced Separation Of Concerns(先進的なSOC)」とも呼ばれているが、「Aspect」というキーワードはSOCにおける「Concerns」と同義であると考えて構わないのではないだろうか。もう少し厳密にいうならば、アスペクト指向は「横断的関心事(Cross-Cutting Concerns)」を扱うパラダイムである。
オブジェクト指向によって「関心事の分離」は完成したかに見えたが、オブジェクト指向が実践で活用されるようになると新たな問題点が明らかになってきた。分離された各モジュール内に別のモジュールを呼び出す処理が散在してしまうという問題点である。この散在する記述こそが、まさに「横断的関心事」と呼ばれているものである。
「横断的関心事」の例としては「ロギング」が有名である。オブジェクト指向によって「ロギング」という役割を持ったオブジェクトを分離するまではできたのだが、ロギング処理が必要となる各モジュール内ではロギングモジュールを利用する記述が必要になる(具体的にはインスタンスの生成とメソッド・コールなど)。
ログを取ることはソフトウェアにとっては非常に重要なことではあるが、中心となるビジネス・ロジックではない。そして、このような副次的な処理は往々にしてコードの至る所に、横断的に「散在」してしまうのである。散在した「横断的関心事」はソフトウェアの保守性を妨げる大きな原因となることは容易に想像できるだろう。さらに、例に挙げたロギングだけでなく、次のようなさまざまな「横断的関心事」がソフトウェアには存在するのである。
- プーリング/キャッシング
- 永続化処理
- パフォーマンスの最適化
- プログラミング・ポリシーの強制
- アクセス・コントロール(セキュリティ)
- デザイン・パターンの適用
- etc……
アスペクト指向では、上記に挙げたような「横断的関心事」をいかに分離するかという点に着目する。そして、具体的にアスペクト指向をプログラミングとして実践するための手法が「AOP(Aspect-Oriented Programming)」なのである。
このようにアスペクト指向は、オブジェクト指向だけでは解決が困難であった問題点を解決しようという試みであり、オブジェクト指向に取って代わるものではなく補完するものであるということが分かっていただけただろうか。
AOPの実装
OOPというプログラミング・パラダイムを実装した言語として「Smalltalk」や「C++」「Java」「Ruby」など多くを挙げることができ、同じようにAOPにもさまざまな実装がある。AOPというパラダイムは決してJavaに限定されるものではないが、「既存のプログラミング言語の機能を補完する」というAOPの性格上、現時点ではJavaによる実装が多いのは確かだろう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
また、単純なAOPの実装だけでなく、開発フレームワークとしてAOPを採用しているものもある。AOPフレームワークとしては最近話題の「Spring Framework」や国産DIコンテナとして注目が高まっている「Seasar2」などが挙げられるだろう。AOPを具体的にどのように実装するかについてはいくつかの方法があり、コンパイル時にウィービングを行うものや、実行時にバイト・コードに対してウィービングを行うものなどがある。この辺りの話は次回以降で取り上げていくことにする。
各ベンダのAOPへの取り組み
それでは最後に、主要なベンダ各社のAOPへの取り組みを簡単に紹介しておこう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
AOP普及のための問題点
ここまでざっと紹介してきたように、アスペクト指向とAOPはソフトウェア開発において非常に強力な武器となる可能性を秘めている。ただし、今後AOPが普及していくためにはいくつかの問題点が解決されていかなければならない。最も身近な懸念事項には、「開発者が新しい技術を覚えなければならない」ということが挙げられる。
また、AOPがいくら素晴らしいからといって、やみくもに導入すればいいというわけでもない。JavaやC#といったOOPを採用したからといって、必ずしも「オブジェクト指向」のメリットを生かしたソフトウェアが完成するわけではないのと同じように、単純にAOPを採用しただけで「アスペクト指向」の恩恵が得られるわけではないからである。OOPには適切なOOAD(オブジェクト指向分析・設計)が必要なように、AOPにも適切なAOAD(アスペクト指向分析・設計)が必要なのではないだろうか。
どちらにしても、AOPは単なる一時的流行などではなく、ソフトウェア工学の発展において追究されてきたSOCの一歩進んだ形として今後必ず普及していくだろう。数年前にはオブジェクト指向がそうだったように、いまはアスペクト指向も目新しいものというだけで騒がれている感もあるが、何年か先にはごく普通の一般的な概念としてソフトウェア開発に取り入れられている可能性が高い。
次回から実際にAOPによるプログラミングの実装を紹介していく。まずはAspcetJによるAOPを紹介していくので楽しみにしておいてほしい。
Copyright © ITmedia, Inc. All Rights Reserved.