= AOP (Aspect-Oriented Programming) アスペクト指向プログラミングに 関する十の神話 増原英彦 ([email protected]) 東京大学 大学院 総合文化研究科 第37回情報科学若手の会招待講演 2004年9月 1 概要 • AOP入門 – モジュール化の意義 – モジュール化のための既存の技術 – 既存の技術の限界 ―― 横断的関心事 – AOP と AspectJの基本機能 • ポイントカット・アドバイス機構 • 型間宣言機構 • 神話 2 お母さんのためのAOP入門 料理のレシピに見る 横断的関心事 3 プログラムとは レシピのようなものだ • 両者とも「どのような順序で どのような操作を行うか」を記述 ビーフカレーの作り方 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参 1本・玉葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カ レールー1箱 1. 牛肉を一口大に切り、サラダ油を熱した鍋で炒める 2. 1に一口大に切ったじゃがいも、人参を加えて炒める 3. 玉葱をみじん切りにして、バターを熱したフライパンで炒める 4. 1に2を合わせ、ベイリーフ、水を加えて30分煮込む 5. アクをとり、カレールーを加えてさらに20分煮込む 4 レシピはモジュール化されてる! 「決定版 はじめての料理」 モジュール化 = 一連の手順に 名前を付け、別に定義すること • 使用側では手順の詳細を 気にしなくてよい • 定義側を独立して変更できる • 同じ手順が何度も出現する 場合に定義を共有できる ― 変更も1回 void みじん切り(材料) { 1. 材料の皮をむく 2. for a in X,Y,Z 材料をa軸方向に4~5mm 間隔に包丁で切る } void 皮をむく(材料) { switch(材料) { case 玉葱: 1. 1に一口大に切ったじゃがいも、人参を 茶色の薄皮を手でむく 2. 玉葱をみじん切りにして、バターを熱した case 人参: 3. 1に2を合わせ、ベイリーフ、水を加えて30 ピーラーを使って… } } 4. アクをとり、カレールーを加えてさらに20分 5 「みじん切り」の効用 「決定版 はじめての料理」 モジュール化 = 一連の手順に 名前を付け、別に定義すること • 使用側では手順の詳細を 気にしなくてよい • 定義側を独立して変更できる • 同じ手順が何度も出現する 場合に定義を共有できる ― 変更も1回 void みじん切り(材料) { 1. 材料の皮をむく 2. for a in X,Y,Z 材料をa軸方向に4~5mm 間隔に包丁で切る } 7. 1に一口大に切ったじゃがいも、 8. にんにくをみじん切りにして、バタ 9. 1に2を合わせ、ベイリーフ、水を 1. 1に一口大に切ったじゃがいも、人参を 10.アクをとり、カレールーを加えて 2. 玉葱をみじん切りにして、バターを熱した 3. 1に2を合わせ、ベイリーフ、水を加えて30 4. アクをとり、カレールーを加えてさらに20分 6 「みじん切り」の効用 「決定版 はじめての料理」 モジュール化 = 一連の手順に 名前を付け、別に定義すること • 使用側では手順の詳細を 気にしなくてよい • 定義側を独立して変更できる • 同じ手順が何度も出現する 場合に定義を共有できる ― 変更も1回 void みじん切り(材料) { 1. 材料の皮をむく 2. for a in X,Y,Z 材料をa軸方向に4~5mm 間隔に包丁で切る } void みじん切り(材料) { 1. 材料の皮をむく 1. 1に一口大に切ったじゃがいも、人参を 2. 材料をぶつ切りにして 2. 玉葱をみじん切りにして、バターを熱した ミキサーで混ぜる } 3. 1に2を合わせ、ベイリーフ、水を加えて30 4. アクをとり、カレールーを加えてさらに20分 7 横断的関心事とは 「本格派」のようなもの • 関心事 = ひとまとまりと考えられる 手順・材料群・コツ・etc. (モジュール = 関心事を ひとまとめに記述したもの) • 横断的関心事 = モジュールに分けて書いたときに、 複数のモジュールにまたがる関心事 – その関心事は散在してしまう – 他の関心事はもつれてしまう 8 横断的関心事とは 「本格派」のようなもの普通の 本格派ビーフカレーの作り方 レシピ 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参1本・玉 葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カレールー1箱・カ レー粉大さじ3・トマトジュース200cc・ヨーグルト1カップ・ガラムマサ ラ適量・ブイヨン3個 void 玉葱を炒める() { 1. 牛肉を一口大に切り、カレー粉小さじ1と一緒にサラダ油を熱した鍋 で炒める 1. 弱火のフライパンでバターを 2. 1に一口大に切ったじゃがいも、人参を加えて炒める 溶かす 2. while (20分過つまで 3. 玉葱をみじん切りにして、バターを熱したフライパンで炒める 飴茶色になるまで) 4. 1に2を合わせ、ベイリーフ、水、ブイヨン、トマトジュースを加えて30 玉葱をかき混ぜる 分煮込む 焦げそうになったときは 5. アクをとり、カレールー残りのカレー粉を加えてさらに20分煮込む フライパンを火から離し 6. 仕上げにヨーグルト1カップを加え混ぜ、ガラムマサラをかける 火力を調節する } 9 横断的関心事とは 「本格派」のようなもの 本格派ビーフカレーの作り方 • 散在 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参1本・玉 葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カレールー1箱・カ • もつれ レー粉大さじ3・トマトジュース200cc・ヨーグルト1カップ・ガラムマサ 1. 2. 3. 4. 5. 6. ラ適量・ブイヨン3個 void 玉葱を炒める() { 牛肉を一口大に切り、カレー粉小さじ1と一緒にサラダ油を熱した鍋 で炒める 1. 弱火のフライパンでバターを 1に一口大に切ったじゃがいも、人参を加えて炒める 溶かす 2. while (20分過つまで 玉葱をみじん切りにして、バターを熱したフライパンで炒める 飴茶色になるまで) 1に2を合わせ、ベイリーフ、水、ブイヨン、トマトジュースを加えて30 玉葱をかき混ぜる 分煮込む 焦げそうになったときは アクをとり、カレールー残りのカレー粉を加えてさらに20分煮込む フライパンを火から離し 仕上げにヨーグルト1カップを加え混ぜ、ガラムマサラをかける 火力を調節する } 10 AOPとは「本格派」を分けて 書く技術 メリット 本格派の場合 • カレールーのかわりにカレー粉 • 「普通のレシピ」と共存 大さじ3を使う • 「本格派」を別レシピに • 牛肉はカレー粉大さじ1を加えて 炒める 時間のない場合 • 玉葱を炒めるときは、飴茶色に 再利用 • 玉葱も一口大に切り、他の野菜 マトンカレーの作り方 なるまでじっくりと。焦げそうに 野菜 カレーの作り方 と一緒に炒める 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参1 なったときはフライパンを火から ビーフカレーの作り方 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参1 本・玉葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カレー • 炒め終わったら圧力鍋で5分間 材料(4人分):牛肉300g・サラダ油大さじ2・じゃがいも4個・人参1 本・玉葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カレー 離し火力を調節する ルー1箱 本・玉葱1個・ベイリーフ1枚・水5カップ・バター大さじ2・カレー ルー1箱 煮る 1. 牛肉を一口大に切り、サラダ油を熱した鍋で炒める ルー1箱 • 具を煮込む際に、ブイヨン3個と 1. 牛肉を一口大に切り、サラダ油を熱した鍋で炒める 2. 1に一口大に切ったじゃがいも、人参を加えて炒める 1. 牛肉を一口大に切り、サラダ油を熱した鍋で炒める トマトジュース200ccを加える 2. 1に一口大に切ったじゃがいも、人参を加えて炒める 3. 玉葱をみじん切りにして、バターを熱したフライパンで炒める 2. 1に一口大に切ったじゃがいも、人参を加えて炒める 3. 玉葱をみじん切りにして、バターを熱したフライパンで炒める 4. 1に2を合わせ、ベイリーフ、水を加えて30分煮込む • 仕上げにヨーグルト1カップを加 3. 玉葱をみじん切りにして、バターを熱したフライパンで炒める 4. 1に2を合わせ、ベイリーフ、水を加えて30分煮込む 5. アクをとり、カレールーを加えてさらに20分煮込む 4. 1に2を合わせ、ベイリーフ、水を加えて30分煮込む え、ガラムマサラをかける 5. アクをとり、カレールーを加えてさらに20分煮込む 5. アクをとり、カレールーを加えてさらに20分煮込む 11 以上、 お母さんのためのAOP入門 ―本題― プログラミング言語では? 12 プログラミング言語における モジュール化とは何か? 「1つ」の操作や値を1まとめにして インターフェースを決めること • 1まとめ → 使う側は細部を 忘れることができる • インターフェース (型・仕様・etc.) ← 「使う側」に対する約束 → 「中身」を「使う側」と 独立して変更できる 13 モジュール化のための技術 対象 操作 値 操作と値 モジュール 技術 サブルーチン・関数・手続き 構造体・レコード 抽象データ型・クラス・structure コンポーネント・functor 14 モジュール化の例 (OOP) • 図形エディタ [Kiczales, et al. 2001] – 特徴: Illustratorのようなもの • 「点」「線」「円」などの部品単位で描画・操作できる • 対話的な描画―移動すると再描画 • モジュール化の方針 – 図形要素をクラスに – 「移動」「描画」等の操作をメソッドに 16 モジュール化の例 (OOP) • 図形エディタ class FigElm { void moveby(int dx, int dy); void display(Display d); } class Display { static List<FigElm> figures = …; static void redraw() {display.draw();} void draw() { for (fig : figures) fig.draw(d); } } 図形の形による • 違いを隠す class Point extends FigElm { class Line extends FigElm { • 共通する性質を int x, y; Point p1, p2; 「線」の内部表現と int getX() { return x; } Point getP1 () { return p1; } まとめる int getY() { … } Point getP2() { … } 使い方を分離 void moveby(int dx, int dy) void moveby(int dx, int dy) { { x+=dx; y+=dy; Display.redraw(); } void setX(int x) { this.x = x; Display.redraw(); } void setY(int y) { … } void draw(Display d) { … } } p1.moveby(dx,dy); p2.moveby(dx,dy); Display.redraw(); } void setP1(Point p1) { this.p1 = p1; Display.redraw(); } void setP2(Point p2) { … } void draw(Display d) { … } } 17 複雑なデータを1つの 値として扱える Q: 横断的関心事は何? • 図形エディタ class FigElm { void moveby(int dx, int dy); void display(Display d); } class Point extends FigElm { int x, y; int getX() { return x; } int getY() { … } void moveby(int dx, int dy) { x+=dx; y+=dy; Display.redraw(); } void setX(int x) { this.x = x; Display.redraw(); } void setY(int y) { … } void draw(Display d) { … } } class Display { static List<FigElm> figures = …; static void redraw() {display.draw();} void draw() { for (fig : figures) fig.draw(d); } } class Line extends FigElm { Point p1, p2; Point getP1() { return p1; } Point getP2() { … } void moveby(int dx, int dy) { p1.moveby(dx,dy); p2.moveby(dx,dy); Display.redraw(); } void setP1(Point p1) { this.p1 = p1; Display.redraw(); } void setP2(Point p2) { … } void draw(Display d) { … } } 18 A:図形が変化する度に再描画 class FigElm { void moveby(int dx, int dy); void display(Display d); } 縺れ class Point extends FigElm { int• x,抽象図形として y; int getX () { return x; } 利用するときに邪魔 int getY() { … } void moveby(int dx, int dy) { x+=dx; y+=dy; Display.redraw(); } void setX(int x) { this.x = x; Display.redraw(); } void setY(int y) { … } } class Display { static List<FigElm> figures = …; static void redraw() { … } } 散在 • 再描画の class Line extends FigElm { 方針変更時に Point p1, p2; Point getP1 () { return p1; } 変更箇所が沢山 Point getP2() { … } void moveby(int dx, int dy) { p1.moveby(dx,dy); p2.moveby(dx,dy); Display.redraw(); } void setP1(Point p1) { this.p1 = p1; Display.redraw(); } void setP2(Point p2) { … } } 19 アスペクト指向プログラミング (AOP) • 横断的関心事をモジュール化する技術 [Kiczales+97] 複数のモジュールにまたがる 操作や構造の記述手段 • 具体的な処理系: AspectJ [Kiczales+01], 他多数 • 典型的応用: ログ・デバグ・最適化・ セキュリティ等のモジュール化 21 AspectJ入門: 適用結果 • 図形エディタ class FigElm { void moveby(int dx, int dy);} class Display { static List<FigElm> figures = …; static void redraw() {display.draw();} void draw() { for (fig : figures) fig.draw(d); } } 描画方針と独立 class Point extends FigElm { int x, y; int getX() { return x; } int getY() { … } void moveby(int dx, int dy) { x+=dx; y+=dy; } void setX(int x) { this.x = x; } void setY(int y) { … }} 図形が変化する 度に再描画する “アスペクト” class Line extends FigElm { aspect DisplayUpdating { Point p1, p2; pointcut Point getP1() { return p1; } move() : Point getP2() { … } call(int FigElm.moveby(int,int)) || void moveby(int dx, call(void int dy) { Point.setX(int)) || Point.setY(int)) || p1.moveby(dx,dy); call(void p2.moveby(dx,dy);} || void setP1(Point p1) call(void { this.p1 Line.setP1(Point)) = p1; } void setP2(Point p2)call(void { … } } Line.setP2(Point)); after() : move() { Display.redraw(); } void FigElm.draw(Display d); void Point.draw(Display d) { … } …} 22 AspectJの主要概念 • アスペクト (cf. クラス) 横断的関心事をまとめる単位 • アドバイス (cf. メソッド) 動作 追加的な操作 • ポイントカット (cf. シグネチャ) 適用時点を決める • 型間定義 追加的宣言 構造 23 AspectJの主要概念 • • • • アスペクト アドバイス ポイントカット 型間定義 •aspect 前後に追加する動作 DisplayUpdating { pointcut move() : • 置き換える動作 call(int FigElm.moveby(int,int)) || cf. CLOS の before / after / call(void Point.setX(int)) || aroundメソッド call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() : move() { Display.redraw(); } moveしたら,その後で Display.redraw()を呼べ void FigElm.draw(Display d); void Point.draw(Display d) { … } …} 24 AspectJの主要概念 • • • • アスペクト アドバイス ポイントカット 型間定義 moveするとは FigElm.moveby, Point.setX, …を 呼び出すこと aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() : move() { Display.redraw(); } • メソッド呼出・フィールド void FigElm.draw(Display d); アクセス・コンストラクタ void Point.draw(Display d) { … } 実行・例外発生・etc. …} • 組み合わせ・名前付け 25 AspectJの主要概念 • • • • アスペクト アドバイス ポイントカット 型間定義 FigElmクラスにdraw メソッドを追加 DisplayUpdating { •aspect メソッド・フィールドの追加 pointcut move() : • 親クラス・実装クラスの追加 call(int FigElm.moveby(int,int)) || call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() : move() { Display.redraw(); } void FigElm.draw(Display d); void Point.draw(Display d) { … } …} 26 Java AspectJの実行モデル ====== class FigElm { … } p.setX(10); setX(10)を 呼び出す Point x=110 y=3 class Point { int x, y; int getX() void moveby(int,int) void setX(int) } class Display { … } class Line {… } class Main {… } aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || …; after() : move() { … } void FigElm.draw(Display d); void Point.draw(Display d) { … } …} 27 AspectJの実行モデル fig.draw(d); p.setX(10); drawを 呼び出す setX(10)を 呼び出す Point x=110 y=3 class FigElm { … } class Point { int x, y; int getX() void moveby(int,int) void setX(int) } 画面を 更新 class Display { … } class Line {… } class Main {… } aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || …; after() : move() { … } void FigElm.draw(Display d); void Point.draw(Display d) { … } …} ポイントカットに 合致 アドバイス本体を実行 結合点と呼ぶ 追加されたメソッドを実行 28 AspectJの実行モデル • ポイントカット+アドバイス機構 – メソッド呼び出し等の各動作(=結合点)が – ポイントカットに合致した場合に – アドバイスを前,後,あるいは置き換えて実行 • 型間宣言機構 – 各クラス(=結合点)が – 型パターンに合致した場合に – メソッド等の宣言が追加されたものとして扱う 29 what’s good? ― ポイントカット! • FigElm・Point・Line に対する動作 → まとめて指定 ↓ 横断的関心事を モジュール化! aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || call(void Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() : move() { Display.redraw(); } …} 30 what’s good? ― ポイントカット! DisplayUpdating { • ワイルドカードに aspect pointcut move() : call(int FigElm.moveby(int,int)) || よって簡潔に call(* FigElm+.set*(..)); 定義できる : move() { Display.redraw(); } • 例: FigElmとその after() …} 子クラスにある “set”で始まる名前のメソッドが 呼び出されたとき 31 what’s good? ― ポイントカット! • 複雑な条件も 指定できる Q: p.moveby(2,3);は 何回redrawを呼ぶ? A: 3回 1回にするには? aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || call(* FigElm+.set*(..)); after() : move() { Display.redraw(); } …} class Point … { void moveby(int dx, int dy) { setX(getX()+dx); setY(getY()+dy); } } 32 what’s good? ― ポイントカット! • 複雑な条件の例: 「move()の中から 呼ばれたものを除く move()」 setX after() : move() …} && !cflowbelow(move()) { … } setY moveby main aspect DisplayUpdating { pointcut move() : call(int FigElm.moveby(int,int)) || call(* FigElm+.set*(..)); class Point … { void moveby(int dx, int dy) { setX(getX()+dx); setY(getY()+dy); } } 33 AspectJ入門: まとめ • アスペクト: 横断的関心事のためのモジュール • ポイントカット+アドバイス: 複数のモジュールで起きる動作に対し 動作を追加する機構 • 型間定義 複数のモジュールに対し, 宣言を追加する機構 対象を指定する方法が強力 (e.g.,ポイントカット) 34 AOPにまつわる神話 • AOPの生い立ち サブジェクト指向 プログラミング 適応的 プログラミング 開放型 実現 自己反映 プログラミング 特定領域向けAOP (分散・並列・・・) 汎用AOP 35 神話一: AOPはオブジェクト指向 の次に来るパラダイムだ • プログラム言語は構造化プログラミング→ 抽象データ型→オブジェクト指向→ アスペクト指向と進化している • AOP オブジェクト指向の置き換え – むしろ追加的な機構 36 神話二: AOPはOOPの 欠点を改善する技術だ • クラス・メソッドを使っても 上手くモジュール化できなかったものを モジュール化するための技術 • OOPに限らず モジュールのある言語に有効 – AspectC [Coady他02] – AspectML [Dantas, Walker03] – レシピ!? 37 神話三: アスペクトととは 従属的なモジュールだ • 支配的なモジュール: 例) 図形の種類 → クラスでモジュール化 • 従属的モジュール: 例) 画面更新 → アスペクトでモジュール化 • 対等なモジュール分割どうしを合成する という考え方もあるHype/J [Ossher,Tarr01], CME + = 38 Hyper/J [Ossher01] • 関心事ごとにクラス階層を作成 (支配的なモジュールがない) • 階層どうしを合成して実行 – 合成方法を指定する言語 • 既存プログラムから 関心事を抽出 Observable moved() { display.update(this); } Display update(FigElm) display Figure elements Point getX() getY() setX(int) setY(int) moveBy(int,int) FigElm Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int,int) Display update(FigElm) 39 神話四: AOPは名前ベースの技術だ aspect DisplayUpdating { • ポイントカットは pointcut move() : メソッドの名前を call(int FigElm.moveby(int,int)) || 使って時点を指定 call(* FigElm+.set*(..)); →名前を正しく after() : move() { Display.redraw(); } …} 付けないとダメ • 現状はその通り • 「意味」に基くポイントカットが研究中 – 呼出し文脈: cflow・実行履歴 [Walker]・将来の呼出し 可能性: predicted cflow [Kiczales03]・データフロー [河内・増原03]・条件分岐, ループ 40 神話五: AOPはプログラム変換だ • アスペクトとは、元のプログラムに埋め込まれて 実行されるコードである → つまりAOPはプログラム変換の一種 • コードの埋め込み以上のことができる – 例: 「setXが実行時にmoveByを経ずに 実行されたときには再描画」 • コード変換に依らない処理系もある – steamloom:仮想機械による織り込み[Bockisch他04] – Wool:VMフックによる織り込み[佐藤・千葉・立堀03] 41 神話六: AOPは遅い • メソッド起動のたびにいちいちアドバイスを 探すのでオーバーヘッドが大きい • 実際はそうでもない – コンパイル時にアドバイスを埋め込む [Hilsdale,Hugnin04][増原・Kiczales・Dutchyn03] – 静的解析による/実行時の最適化 [Sereni,de Moor03][Hanenberg, Hirschfeld, Unland04] – オーバーヘッドの計測 [Dufour et al.04] 42 神話七: AOPはログをとるための技術だ • それ以外の応用ってあるの? • ログ以外にも最適化・エラー処理などへの 実際的な応用がある – FreeBSDカーネルをAOPで分離 [Coady他02,03] アスペクト: プリフェッチ・クォータ・ スケジューリング – WebSphereのコードをAOPで分離[Coyler04] アスペクト: ログ・エラー処理・監視 43 see: Y. Coady, G. Kiczales M. Feeley and G. Smolyn, Using AspectC to improve the modularity of path-specific customization in operating system code, in Proceedings of ESEC-8 / FSE-9, pp.88-98, 2001,Vienna, Austria. 44 神話八: AOPなんかいらない、 デザインパターンで充分 • 「画面の再描画」は Subject-Observerパターンで実現可能 • 「実現」はできるが、 – 記述は散在してしまう – パターンを再利用できない (AOPなら可能になる場合も[Hannemann他02]) 45 神話九: AOPはプログラミングを 難しくする • AOPで例えば「画面更新」を分離 →Point, Lineの定義から「画面更新」が無くなる →「画面更新」の影響範囲が特定できない →誤りを見つけるのが難しくなる • 開発ツールによる支援 – AJDT [Kiczales他01,…] • OOPでも同じ議論が可能? →継承によって一部の定義を子クラスに →親クラスの定義の影響範囲が特定できない 46 see: Kersten, Clement, and Harley, AspectJ Tools - New and Noteworthy, AOSD 2004 Demo. 47 神話十: アスペクトは リファクタリングで抽出するもの ※ リファクタリング = プログラムの機能を変えずに 構造を改良する技術 • 横断的関心事は,プログラムを作ってみないと 「横断的」かは分からないだろう • そういう例は多い • 研究レベルでは,アスペクトの利用を前提とした 開発方法論が提案 – “Early Aspects” / “Aspect-Oriented Modeling” / Use-case Pointcuts [Sillito,Dutchyn,Eisenberg,De Volder04] 48 まとめにかえて: AOPの現状と将来 現状 • 沢山の懐疑論者 – 「便利そうだけど,大きな プログラムは書けない?」 – 「同じことは××機構で 頑張ればできるよ?」 – 「××には使えないよ?」 将来 1980年代のOOP • 沢山の言語・技術が提案 (Smalltalk, C++, Flavors, バイトコード, JITコンパイ ル, GC, IDE…) • 理論よりも実践が先行 • それから「当たり前」にな るのに10年 当たり前 or 「そういえば昔, AOPなんてのがあったなあ」 49 プログラミング言語の歴史 1955 Fortran Lisp 1960 Algol-60, COBOL 現存する最古の言語達 1965 最初のオブジェクト指向言語 1970 1975 1980 1985 モ PL/1 ジ ュ Simula-67 goto有害説ー 階 Smalltalk, C ル 層 Prolog Scheme 化 性 ・ Smalltalk-80 再 Ada C++ SML 利 Perl 用 実用的なオブジェクト指向言語 1990 Haskell Python SOP Ruby 1995 Java, GoF “Design Patterns” 2000 C# オブジェクト指向があたり前の時代 AspectJ 0.3AspectJ 1.0 最初の汎用AOP言語 実用的AOP言語 50 情報源など • 会議・論文誌 – Aspect-Oriented Software Development (AOSD) OOPSLA, ECOOP, ICSE, FSE, ICFP, … – Trans. AOSD (Springer) • ポータルサイト: aosd.net • メール: – [email protected] – [email protected] – [email protected] • Kiczales’ talk @ ソフトウェア科学会大会 (2004年9月15日, 東工大) 51 おまけ 52
© Copyright 2024 ExpyDoc