690 likes | 950 Views
組込みソフトウェアシンポジウム ESS 2004. アスペクト指向 ソフトウェア開発. 九州工業大学 情報工学部 知能情報工学科 鵜林尚靖 2004年10月15日. 内容. アスペクト指向が生まれた背景 アスペクト指向の考え方 様々なアスペクト指向メカニズム アスペクト指向の適用事例 アスペクト指向とMDA アスペクト指向の今後. 1.アスペクト指向が 生まれた背景. ソフトウェア開発手法の変遷. 60. 70. 80. 90. 2000. 年代. 年代. 年代. 年代. 年代. 構造化手法. オブジェクト指向手法.
E N D
組込みソフトウェアシンポジウム ESS 2004 アスペクト指向ソフトウェア開発 九州工業大学 情報工学部 知能情報工学科 鵜林尚靖 2004年10月15日
内容 • アスペクト指向が生まれた背景 • アスペクト指向の考え方 • 様々なアスペクト指向メカニズム • アスペクト指向の適用事例 • アスペクト指向とMDA • アスペクト指向の今後
ソフトウェア開発手法の変遷 60 70 80 90 2000 年代 年代 年代 年代 年代 構造化手法 オブジェクト指向手法 構造化プログラミング 構造化分析 構造化設計 OOP OOA OOD パターン フレームワーク コンポーネント EA プロダクトライン アジャイル, XP MDA アスペクト指向
アスペクト指向とは何? 一言でいうと 「モジュール化メカニズム」の一つ
モジュール化メカニズムの歴史 構造化 機能中心のため、データの変更に対して脆い データ抽象 データとそれに関連する操作をまとめてしまおう 抽象データ型 データとそれに関連する操作をまとめて型にしよう オブジェクト指向 継承機構も入れて、再利用性を高めよう
モジュール化メカニズムの発展 ~ 構造化 からオブジェクト指向 へ ~ 操 作 操 作 オブジェクト 操 作 操 作 データ データ 操 作 データ 操 作 データ データ オブジェクト 操 作 操 作 オブジェクト 操 作 操 作 データ 操 作 データ データ オブジェクト指向 構造化 変更の影響範囲が オブジェクト内に カプセル化される データを変更すると周りの 操作に影響が波及する
モジュール化の理想像 ソフトウェア構造 要求分析 設計 実装 問題 領域 分析時の 関心事 設計時の 関心事 モジュールの 構成 • 問題領域の構造がソフトウェア構造に対応する • ソフトウェア構造を構成する関心事を自然にモジュール化できる (関心事の分離 “Separation of Concerns” Edsger Wybe Dijkstra )
良いモジュール化 機能要件を きれいにモジュール化 • org.apache.tomcat におけるXML parsing • 赤い線はXML parsingを行うコード行を示す • 1箇所にモジュール化されている AspectJ. http://eclipse.org/aspectj/より抜粋
しかし、ログ処理の場合は... 複数のオブジェクトにまたがる (Crosscutting Concerns) • org.apache.tomcat におけるログ処理 • 赤い線はログ処理を行うコード行を示す • 1箇所ではない • しかも、数多くの場所に分散している(tangling and scattering) AspectJ. http://eclipse.org/aspectj/より抜粋
現実のモジュール化は... ソフトウェア構造 要求分析 設計 実装 問題 領域 分析時の 関心事 設計時の 関心事 モジュールの 構成 (問題意識) 上流の関心事が、下流に行くにしたがって構造的に分散してしまう (オブジェクト指向でも解決できない問題がある)
オブジェクト指向の限界 オブジェクト指向プログラミングは、機能要件のカプセル化には優れているが、横断的関心事( Crosscutting Concerns )の表現には必ずしも向いていない。 <横断的関心事の例> ・エラーチェック戦略 ・セキュリティ ・デザインパターン ・同期制御 ・資源共有 ・分散にかかわる関心事 ・性能最適化 性能最適化のためのコードを追加しようとすると、コードが複数のオブジェクトに分散してしまい、見通しの悪いプログラムになってしまう。「分かりやすく性能も良い」プログラムを作るのが難しい。 AOP
組込みソフトウェア設計の難しさ • 現在のソフトウェア技術では、機能的合成可能性が物理的合成可能性を意味するものではない。 • 実際、物理特性は合成可能ではない。むしろ、開発プロセスにおいて、横断的制約(cross-cutting constraints)として現れる。 • このような横断的制約は設計をやり難くしてしまう可能性がある。 Janos Sztipanovits and Gabor Karsai: Generative Programming for Embedded Systems, GPCE2002, LNCS2487, pp.32--49, 2002
組込みソフトウェアの構造 最適化 メモリ容量 HW特性 応答性 きれいなプログラムを作成したい! でも、HW特性、性能向上、例外のためのコードを追加すると どんどんプログラムが汚くなってしまう。。。 アスペクト指向
アスペクト指向を実現する言語処理系、システムアスペクト指向を実現する言語処理系、システム • AspectJ (Gregor Kiczales, et.al.) • Hyper/J (Harold Ossher, et.al.) • DemeterJ (Karl J. Lieberherr, et.al.) • Composition filters (Mehmet Aksit, et.al.) • JBoss-AOP • AspectWerkz など多数
2.アスペクト指向の 考え方 ~ AspectJ を中心に ~
AspectJ • 最も代表的なAOP言語 • AOPの基本的な考え方をJava上に実現した言語 • 元々はPARCで開発。現在はEclipseプロジェクトに移管。 AspectJ: http://eclipse.org/aspectj/
開発環境: AJDT • Eclipse Tools Projectの1つ。 • AJDT(AspectJ Development Tools)は、AspectJを用いたアスペクト指向開発を支援するためのツールをEclipse上に提供する。 • AJDTを用いることにより、JDT(Java Development Tools)上でAspectJの機能が使用できるようになる。 AJDT: http://eclipse.org/ajdt/
AspectJによるプログラミング方式 同期制御、資源共有、性能最適化など複数のオブジェクトにまたがる関心事をアスペクトというモジュール概念を用いて記述 オブジェクト (通常の機能) weaver プログラム アスペクト (オブジェクトに またがる関心事) ・複数のオブジェクトにまたがる関心事を見通しよく記述できる! ・「分かりやすく性能も良い」プログラムが作れる!
AspectJの主要概念 振る舞いへの作用 • ジョインポイント(join point) • ポイントカット(pointcut) • アドバイス(advice) 構造への作用 • インタータイプ定義 • declare句による宣言
簡単なAspectJプログラム アスペクト インタータイプ 定義 HelloWorld.java Trace.java public class HelloWorld { public static void main ( String [], args) { HelloWorld app = new HelloWorld (); app.hello(); } void hello() { System.out.println(“こんにちは!”); } } public aspect Trace { private String HelloWorld.mes = “トレース”; public pointcut atHello() : call (void HelloWorld.hello()); before(HelloWorld h) : atHello() && target(h) { System.out.println(h.mes + “呼び出し前”); } after(HelloWorld h) : atHello() && target(h) { System.out.println(h.mes + “呼び出し後”); } } ポイントカット アドバイス 「AspectJによるアスペクト指向プログラミング入門」 長瀬、天野、鷲崎、立堀(著) より
JPM(Join Point Model) public aspect Trace { private String HelloWorld.mes = “トレース”; public pointcut atHello() : call (void HelloWorld.hello()); before(HelloWorld h) : atHello() && target(h) { System.out.println(h.mes + “呼び出し前”); } after(HelloWorld h) : atHello() && target(h) { System.out.println(h.mes + “呼び出し後”); } } メソッド呼び出し、 変数参照/更新など の実行点を捕まえる weaving トレースコードの埋め込み (advice) プログラム上の様々な実行点 (join point) 実行点の中からトレース処理に関わる部分を抽出 実行点の取り出し (pointcut)
Figure FigureElement moveBy(int, int) makePoint(..)makeLine(..) Point Line getX()getY()setX(int)setY(int)moveBy(int, int) getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int) operations that move elements 実用的な例: 簡易図形エディタ Display * 2 AspectJ. http://eclipse.org/aspectj/より抜粋
通常の保守、改良 class Line { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } } class Point { privateint x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; } } class Line { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; Display.update(this); } void setP2(Point p2) { this.p2 = p2; Display.update(this); } } class Point { privateint x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; Display.update(this); } void setY(int y) { this.y = y; Display.update(this); } } 変更が複数の クラスに散らば ってしまう! AspectJ. http://eclipse.org/aspectj/より抜粋
AspectJによる保守、改良 class Line { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } } class Point { privateint x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; } } aspect DisplayUpdating { pointcut move(FigureElement figElt): target(figElt) && (call(void FigureElement.moveBy(int, int) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Point.setX(int)) || call(void Point.setY(int))); after(FigureElement fe) returning: move(fe) { Display.update(fe); } } (set* のような記述も可能) 変更が1つのアスペクトに局所化される! 予期しないソフトウェア発展に有効! (unanticipated software evolution) AspectJ. http://eclipse.org/aspectj/より抜粋
Figure FigureElement moveBy(int, int) makePoint(..)makeLine(..) Point Line getX()getY()setX(int)setY(int)moveBy(int, int) getP1()getP2()setP1(Point)setP2(Point)moveBy(int, int) クラスを横断するアスペクト Display * 2 DisplayUpdating AspectJ. http://eclipse.org/aspectj/より抜粋
様々なアスペクト指向メカニズム アスペクト指向 = AspectJ ではない! たとえば、 • PA (AspectJ流 pointcut & advice) • TRAV (DemeterJ流 traversal specifications) • COMPOSITOR (Hyper/J流 class hierarchy composition) • OC (AspectJ 流 open classes ) ※用語は以下のものに準拠 Hidehiko Masuhara and Gregor Kiczales: Modeling Crosscutting in Aspect-Oriented Mechanisms, ECOOP 2003
http://www.cs.ubc.ca/labs/spl/projects/asb.html ASB ASB(Aspect Sand Box) • 4つのアスペクト指向メカニズムをモデル化 • 4つのインタプリタを提供 ここでは、ASBのサンプルプログラム(※)を提示しながら 4つのアスペクト指向メカニズムを紹介する ※ 元々のプログラムはSchemeライクな言語であるが、ここでは、 分かりやすさを考慮してJavaライクな 言語で説明する ※ 以下の論文からの引用 Hidehiko Masuhara and Gregor Kiczales: Modeling Crosscutting in Aspect-Oriented Mechanisms, ECOOP 2003
基盤となる例題プログラム 簡易図形エディタ
PA (AspectJ流 Pointcut & Advice) ASBサンプルプログラム after (FigureElement fe): ( call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point))) && target(fe){ fe.display.update(fe);
TRAV (DemeterJ流) Northeastern大学で開発されたツール/ライブラリで、Javaに よるAdaptive Programmingを支援する ASBサンプルプログラム Visitor counter = new CountElementsVisitor(); traverse("from Figure to FigureElement", fig, counter); [Visitor] Counter fig traverse 仕様に則り、 オブジェクト木を訪問し、 Visitor メソッドを実行 Point
COMPOSITOR (HyperJ流) Hyper/Jとは • IBM T.J Watson Research Centerで開発されたJavaベースの言語。 • SOP(Subject-oriented programming)およびその後継の MDSOC(Multi-Dimensional Separation Of Concerns)という考え方に基づいている。 • すべてを関心事(クラスで表現)としてプログラミングする方式。AspectJのようにアスペクトとクラスといった区分がない。 • ソフトウェアのevolutionへの柔軟な対応を重視。
つづき ASBサンプルプログラム class Observable { Display display; void moved() { display.update(this); } } ; relationship between Point/Line and Observable match Point.setX with Observable.moved match Point.setY with Observable.moved match Line.setP1 with Observable.moved match Line.setP2 with Observable.moved
OC (AspectJ流 Open Class) AspectJ の インタータイプ定義 ASBサンプルプログラム class DisplayMethods { void Point.draw() { Graphics.drawOval(...); } void Line.draw() { Graphics.drawLine(...); } }
疑問... PA TRAV COMPOSITOR OC 同じアスペクト指向と言っても 全然違うではないか? これらに共通するものは あるのか?
Three-Part Model EFFB - means ofeffecting A - program B - program EFFA IDB IDA- means ofidentifying META -weavingparameter X - computation or program XJP- join point Hidehiko Masuhara and Gregor Kiczales: Modeling Crosscutting in Aspect-Oriented Mechanisms, ECOOP 2003
Three-Part Model (つづき) c, m, f: class, method, field の略
アスペクト指向の適用事例 デバッグやロギングについてはメリットは分かるが、 それ以外の応用はどうなのか? デザインパターンへの応用 [Hannemann他02] データベースへの応用 [Rashid他03] FreeBSDカーネルの最適化コードをAOPで分離 [Coady他02,03] WebSphereのコードをAOPで分離 [Coyler04]
事例1: デザインパターンへの応用 Jan Hannemann and Gregor Kiczales: Design Pattern Implementation in Java and AspectJ, OOPSLA2002 (2002) AspectJを持いて、GoFデザインパターンの記述を改良
Observer パターン * 1 Observer Subject o Update() Attach(Observer) Detach(Observer) Notify() for(;全てのObserver;) {o->Update();} 1 1 ConcreteObserver ConcreteSubject subject observerState:State* subjectState:State* GetState() Update() observerState = Subject->GetState(); return subjectState;
Observer パターンの適用例 Jan Hannemann and Gregor Kiczales: Design Pattern Implementation in Java and AspectJ, OOPSLA2002 (2002) より引用
Observerパターンの汎用アスペクト 抽象ポイントカット 抽象アスペクト インタフェース アドバイス Jan Hannemann and Gregor Kiczales: Design Pattern Implementation in Java and AspectJ, OOPSLA2002 (2002) より引用
実際のプログラムへの適用 具象ポイントカット Jan Hannemann and Gregor Kiczales: Design Pattern Implementation in Java and AspectJ, OOPSLA2002 (2002) より引用
事例2: データベースへの応用 永続性(Persistence)は横断的関心事の1つ • アスペクト指向により、永続性をモジュール化したい • 永続アスペクトを再利用したい • 永続性のことを気にせずにアプリケーションを開発したい Aspect-Oriented Database Awais Rashid and Ruzanna Chitchyan: "Persistence as an aspect", AOSD2003
アスペクト化された永続性(1) 例: 文献管理アプリケーション データアクセスに関わる join pointを抽出し、そこに DB処理のためのコードを weavingする
アスペクト化された永続性(2) AspectJ による記述 public abstract aspect DatabaseAccess { private static Connection dbConnection; private static String dbURL; abstract pointcut establishConnection(); abstract pointcut closeConnection(); public abstract String getDatabaseURL(); public abstract String getDriverName(); pointcut trapInstantiation() : call(PersistentRoot+.new(..)); pointcut trapUpdates(PersistentRoot obj) : !cflow(call(public static Vector SQLTranslation.getObjects(ResultSet, String))) && (this(obj) && execution(public void PersistentRoot+.set*(..))); pointcut trapRetrievals() : call(Vector PersistentData.get*(..)); public static PersistentData getPersistentData() { … } : : // advice code } public class PersistentRoot { protected boolean isDeleted = false; public void delete() { this.isDeleted = true; } public boolean isDeleted() { return this.isDeleted; } } public aspect ApplicationDatabaseAccess { declare patents: (BibliographyItem || AuthorEditor || Publisher || PublisherLocation) extends PersistentRoot; // other code } Connection Storage & Update Retrieval
永続化フレームワーク アスペクトベースの永続化フレームワーク アプリケーション Weaving 永続性の部分をアスペクト化することにより、アプリケーションは永続性のことを気にせずに開発できる(一部例外あり)。