複数個のJoinpointの集合を 対象としたPointcutを 記述可能なアスペクト指向言語

Slides:



Advertisements
Similar presentations
Web アプリをユーザー毎に カスタマイズ可能にする AOP フレームワーク
Advertisements

~手続き指向からオブジェクト指向へ(Ⅰ)~
Javaのための暗黙的に型定義される構造体
Myoungkyu Song and Eli Tilevich 発表者: 石尾 隆(大阪大学)
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
AspectScope によるアスペクトとクラスのつながりの視覚化
ユースケース図2-4~ FM11012 中島拓也.
リファクタリングのための 変更波及解析を利用した テスト支援ツールの提案
同期的にアドバイスを活性化できる分散動的アスペクト指向システム
UMLとは           032234 田邊祐司.
アスペクト指向プログラミングを用いたIDSオフロード
アスペクト指向プログラミングと Dependency Injection の融合
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
遠隔ポイントカット - 分散アスペクト指向プログラミング のための言語機構
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
細かい粒度で コードの再利用を可能とする メソッド内メソッドと その効率の良い実装方法の提案
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
関心事ごとに視点を切り替えて プログラムを編集できる 統合開発環境の提案と実装
コードクローンの分類に基づいた メソッド引き上げ手順の提案とその有効性評価
理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 03_03686 内河 綾
オブジェクト指向 プログラミング 第十四回 知能情報学部 新田直也.
Javaプログラムの変更を支援する 影響波及解析システム
アスペクト指向に基づく 拡張可能な MDAモデルコンパイラ
横断的関心事に対応したオブジェクト指向言語GluonJとその織り込み関係の可視化ツール
動的データ依存関係解析を用いた Javaプログラムスライス手法
豊富な情報を基にした pointcut を記述できるアスペクト指向言語
オブジェクト指向言語論 第八回 知能情報学部 新田直也.
コードクローン検出に基づくデザイン パターン適用支援手法の提案と実現
クラスのインターフェース やその振る舞いに及ぼすアスペクトの影響の解析と可視化
アスペクト指向言語のための 独立性の高いパッケージシステム
アプリケーション依存の先読みが可能なO/Rマッピングツール
バイトコードを単位とするJavaスライスシステムの試作
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
pointcut に関して高い記述力を持つ アスペクト指向言語 Josh
プログラムの織り込み関係を可視化するアウトラインビューの提案と実装
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
分散 Java プログラムのための アスペクト指向言語
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
Josh : バイトコードレベルでのJava用 Aspect Weaver
統合開発環境によって表現された 言語機構によるコードのモジュール化
IDE を活用した言語機構に頼らないコード再利用のためのモジュール化
同期処理のモジュール化を 可能にする アスペクト指向言語
C#プログラミング実習 第3回.
設計情報の再利用を目的とした UML図の自動推薦ツール
「マイグレーションを支援する分散集合オブジェクト」
アスペクト指向言語のための視点に応じた編集を可能にするツール
プログラムの差分記述を 容易に行うための レイヤー機構付きIDEの提案
サブゼミ第7回 実装編① オブジェクト型とキャスト.
アルゴリズムとデータ構造1 2009年6月15日
状況に応じて適切な 例外処理が行なえる アスペクト指向分散環境実験の 支援ツール
プログラム分散化のための アスペクト指向言語
ロールを基にした構造進化の表現 Role based Evolution Dependency Structure Matrix
統合開発環境のための プログラミング言語拡張 フレームワーク
開発者との対話を活かした 横断的構造の表現
JAVA入門⑥ クラスとインスタンス.
アルゴリズムとデータ構造 2010年6月17日
ソフトウェア工学 知能情報学部 新田直也.
コードクローン解析に基づく デザインパターン適用候補の検出手法
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語における セキュリティ解析アルゴリズムの提案と実現
GluonJ を用いたビジネスロジックからのデータベースアクセスの分離
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
Josh : バイトコードレベルでのJava用 Aspect Weaver
Presentation transcript:

複数個のJoinpointの集合を 対象としたPointcutを 記述可能なアスペクト指向言語 理学部 情報科学科 指導教官 千葉 滋 助教授 学籍番号 01_14577 竹内 秀行

異なるクラス階層を持つ変更 既存のソフトウェアに新しい役割を持たせる オブジェクト指向で設計すると階層構造が破綻 別々に記述できたほうが開発しやすい 人材管理モジュール 給与台帳モジュール 平社員 管理職 調査部 販売部 社員 販売担当 調査担当 調査担当部長 販売担当部長 近年、ソフトウェアの開発手法や、運営手法が変化してきており、 一度出荷したソフトウェアに対して新たな機能を追加することで 利益を上げるモデルが、中規模程度のソフトウェアで採用される ことが多くなってきています。 このようなモデルで開発・運営するときに重要となるのが、 いかに既存のソフトウェアに対する変更のコストを下げるか、 という部分になるのですが、ここにソフトウェアに対して 変更を加える技術としてアスペクト指向を活用することが 最近期待されてきています。 まあ、オブジェクト指向でも変更に対する柔軟性を持たせる ための技術はいくつもあるがすべての変更を予測することは 不可能ですし、また、そのような設計は費用とかコードとか 開発期間とかの肥大化を招きます。 さて、このようにアスペクト指向で解決されることが求められている 問題の中に、異なるクラス階層を持つ変更というものがあります。 これはどのようなものかというと、下の図を見ていただけると わかりやすいと思いますが、ある会社で社員の人材管理のための システムが採用されており、ここに、新たに 給与台帳の機能を持たせたいという要求があったとします。 このとき、図を見るとわかるように人材管理のパッケージと 給与台帳のパッケージが全く異なったクラス階層を 構成していたとします。こういうことはしばしばあることで、 この例の場合では、管理職と平社員では当然必要とされる 能力が違いますし、給料は調査部は固定給、販売部は 歩合制といった部署によって計算方法が異なっているとすると、 それぞれ、このような階層構造をとるのはわかると思います。 それぞれ別々のクラス階層として使うこともできるのですが、 ある上司の部下の給料はいくらだなどという統計がほしいと いう要求があった場合設計が複雑になってきます。 だからといって、これをそのままオブジェクト指向で表現しようと するとどちらか一方の階層構造にもう片方のパッケージの内容を 移すことになり、どちらかの階層構造が破綻してしまいます。 こうなってしまうと、もし新たな要求が出て上位のクラスに 変更を加えようとしたときにどこに元のクラスの内容があるのかが わからなくなってしまいます。 これに対する解法として、開発時にはそれぞれのクラス階層で記述し、 いざ使うというときにそれぞれ同じ対象を表すクラス同士を合成して しまうという方法を考えることができます。 例えばこのようにです。

クラスの合成 人材管理::販売担当 社員管理::販売担当 給与台帳::販売担当 同じ対象を表現するクラス同士を合成する 名前() 表示() 部下() 社員管理::販売担当 名前() 表示() 給料() 部下() 給与台帳::販売担当 名前() 表示() 給料() 同じ対象を表現するクラス同士を合成する それぞれのクラスが持つすべてのメソッドおよびフィールドを一つのクラスから利用できるように メソッド名が衝突した場合のルールは別に記述 実際にこれを実現するにはどのようなことをすればよいかというと、 まず、それぞれのパッケージから同じ対象を表現するクラスを 探してきます。これについては同じ名前のクラスを持ってくるか、 特別な場合には別途ルールを記述すればよいと思います。 その後で、それぞれのクラスが持つすべてのメソッドおよびフィールドを 新しいクラスにコピーし、もしメソッドやフィールドの名前が衝突した 場合のルールは別に記述すればよいと思います。

既存のアスペクト指向言語 AspectJ[Kiczalesら’01] 現在最も一般的なアスペクト指向言語 特徴点 (joinpoint) を探し出しコードを挿入 メソッド呼び出しやフィールドアクセス等 Pointcut Joinpointを抽出するための記述 Advice Joinpointの新しい振る舞いをJavaコードで定義 で、先ほどのクラス階層の合成を、アスペクト指向で解決しようと 思いますので、ここで既存のアスペクト指向言語としてAspectJに ついて解説させていただきます。 これは、現在もっとも一般に普及しているアスペクト指向言語です。 ちょっと、詳しく解説している時間がないので、なにができるのかということ のみを述べさせていただきます。 この言語はまずプログラムにおける特徴点(joinpoint)を検出することができます。 ここで定義されている特徴点とは、インスタンス生成とかメソッドの呼び出しとか フィールドアクセスとか、例外の処理とかいったものがあります。 で、これの検出方法ですが、AspectJにはpointcutという記述がありまして これはここにもありますように call(void System.out.println(..)) && within(Logger) のように記述します。これは、Loggerクラス内のメソッドで、 System.out.println(..)というメソッドが呼び出されているところを 抽出するという意味になります。 次に、この検出された特徴点をどう使うかというと、 ここに対し advice と呼ばれる宣言によって、joinpointの 前後に対してJavaのコードが挿入されます。 ここで書いてある記述では、log()という名前のpointcutで 検出されるjoinpointの前に、現在時間を表示するコードを挿入します。 call(void System.out.println(..)) && within(Logger) before() : log() { System.out.println(“[” + now() + “] ”); }

AspectJによるクラス階層の合成 AspectJでの方針 AspectJの問題点 クラス階層を別々に開発 インスタンス化時に関連付け メソッド呼び出し等をpointcut AspectJの問題点 pointcut で単一の joinpoint しか抽出できない リフレクションを利用しなければならない 一方向にしか関連付けることができない

単一のJoinpointの制限① 人材管理 給与台帳 販売担当 調査担当 Aspect 販売担当 調査担当 Aspect インスタンス化時にClass.forName()で探してバインド インスタンス化を pointcut し、リフレクションで関連付け 実行速度の低下

単一のJoinpointの制限② 人材管理::販売担当 給与台帳::販売担当 Aspect 一方向にしか関連付けることができない 名前() 表示() 給料() 表示() 名前() 部下() 一方向にしか関連付けることができない 基となるモジュールをあらかじめ決める必要がある 逆方向の参照はオブジェクト同士のマッピングが必要

提案:複数個のJoinpointの集合を 選択できるPointcutの記述 pointcut式 ## pointcut式 左右の式で得られるjoinpoint集合の配列を連結 従来の pointcut式の結果 は要素1の配列として扱う 利用例 人材管理パッケージのクラスと給与台帳パッケージのクラスを抽出 Jugglingクラスのstart()とend()の呼び出しを抽出 class(personnel.*) ## class(payroll.*) call(Juggling.start ()) ## call(Juggling.end ())

クラス階層の合成 composition advice の導入 複数のクラスを Joinpoint としてとる Hyper/J[Ossherら’00]の記述を応用 composition() : class(personnel.*) ## class(payroll.*) { mergeByName; override String $2.name() with String $1.name(); String $composed.toString() { StringBuffer ret = new StringBuffer(); for (int i = 0; i < $result.length; ++i) ret.append($result[i]); return ret.toString(); }

Composition Advice mergeByName; 何も指定されなければ同じ名前のメソッドを結合 結合後のメソッドは合成前のクラスのメソッドを順番に呼び出し最後の呼び出しの結果を返り値とする override String $2.name() with String $1.name(); name()メソッドは結合せずに二番目のjoinpointのメソッドを呼び出す $1,$2はpointcutによって得られたjoinpoint配列の要素 String $composed.toString() { … } 結合されたtoString()の返り値を再構成する

実装 拡張可能なコンパイラ コンパイル速度の比較 pointcut および advice を Java で追加可能 Polyglot, Javassistを用いて作成 コンパイル速度の比較 PureTLS Toolkits のコンパイルおよび合成 クラス数: 127個 行数: 約18000行 joinpoint: 6384個 うち合成対象箇所: のべ1052個 単位はms juggler javac1.5 ajc1.2 abc1.0 Aspect無し 18601 2972 4443 23101* Aspect有り 19019 5317 N/A *内部エラーにより終了(バイトコード変換で問題発生)

関連研究 Hyper/J 異なるモジュールの合成を行うアスペクト指向システム メソッド、フィールド、クラスを既存のモジュールから切り出し他のモジュールに合成を行う 自由度が高い反面、ユーザーが面倒を見なければならないところが多い

まとめ 複数個のJoinpointの集合 今後の課題 pointcut式に連結演算子を導入 composition adviceによるクラス階層の合成 今後の課題 pointcut による記述の柔軟性を生かし切れていない advice での joinpointの扱いの整合性がとれていない 他の複数の joinpoint を必要とするアスペクトの記述 本研究では、複数個のJoinpointの集合を扱うことを提案し、 pointcut式に連結演算子を導入すること、および、 クラス階層の合成のためにcomposition adviceを提案した。 今後の課題として、本研究で扱った複数個のJoinpointの集合に よって、他のアスペクト指向言語で扱っているモデルを記述できる 可能性があり、すでに、Event-based AOP や Adaptive Visitor 等の 一部に関しては記述できることを確かめています。これらの 記述可能性について検証しつつ、新しいアスペクトに ついて研究していこうと思う。 また、この研究で扱っている内容については、AspectJ自体が 他のプロダクトにも影響を与えているように、特に言語である 必要がないので、モデルとしての定式化を行っていけたらと 思っています。

おしまい 質問用スライドに続く…

単一のJoinpointの限界③ 人材管理::販売担当 給与台帳::販売担当 Aspect 一つ一つ記述する 役職() 解雇() Aspect 性別() 名前() 表示() 解雇() 備考() 表示() 役職() 名前() 性別() 備考() 一つ一つ記述する メソッド・フィールドごとに一つのアドバイスが必要 保守が難しい

Hyper/Jによる解法 特徴点 (Joinpoint) が二つある 特徴点の抽出 その振る舞いの定義 AspectJと何が違う? package personnel : Feature.Personnel package payroll : Feature.Payroll relationships: mergeByName; override operation Feature.Payroll.name with operation Feature.Personnel.name; AspectJと何が違う? 特徴点 (Joinpoint) が二つある

AspectJ での実際のコード例 public aspect PersonnelWithPayroll perthis(this(personnel.Employee+)) { private payroll.Employee payroll; before(personnel.Employee personnel) : execution(personnel.Employee+.new()) && this(personnel) { String name = personnel.getClass().getName(); name = nameのクラス名だけ取り出す; payroll = Class.forName( “payroll.” +name).newInstance(); } after(String name) : execution(void personnel.Employee+.setName(String)) && args(name) { payroll.setName(name); …