統合開発環境によって表現された 言語機構によるコードのモジュール化 数理・計算科学専攻 10M37143 寺本 裕基 指導教員:千葉 滋 教授
コピー&ペースト開発 同じようなコードを記述するとき使用 手軽で使いやすい 保守性の問題 悪い再利用例 同じようなコードを記述するとき使用 手軽で使いやすい 保守性の問題 一箇所変更すると他のモジュールも変更しなければならない class Rectangle extends Shape { int width, height; void setWidth(int w) { width = w; this.display.update(this); } void setHeight(int h) { height = h; class Circle extends Shape { int radius; void setRadius(int r) { radius = r; display.update(this); }}
関数抽象を用いたモジュール化 メソッドの利用 update処理を一つにまとめること で、保守性を上げる 変更は一箇所で済む 良い再利用例 で、保守性を上げる 変更は一箇所で済む class DisplayUpdate { static void update(Shape s) { s.display.update(s); } class Rectangle extends Shape { int width, height; void setWidth(int w) { width = w; DisplayUpdate.update(this); } void setHeight(int h) { height = h; class Circle extends Shape { int radius; void setRadius(int r) { radius = r; DisplayUpdate.update(this); }}
言語を用いたモジュール化の限界 複雑な言語を導入すれば強力なモジュール化が可能 隠れたコスト パラメータ(関数引数) クラス アスペクト ・・・ 隠れたコスト 新しい言語を導入しなければならない 言語が次第に複雑になる 複雑なので言語を理解するのが難しい 開発環境、ライブラリ、フレームワークなども用意しなければ ならない
アスペクト抽象 あちこちで同じコードが実行されるとき、どこで実行さ れるかを抽象化(一箇所にまとめる) あちこちで個別にメソッド呼び出ししない 複雑 aspect Update { pointcut change(Shape s): execution(void Shape+.set*(..)) && this(s); after(Shape s) : change(s) { s.display.update(s); }} class Rectangle extends Shape { int xpos, ypos; int width, height; void setX(int x) { xpos = x; }}
提案:同期機能付きコピー&ペースト 強化した単一機能でモジュール化 一つの機能を学習すればよい 同期により保守性の問題を解決 統合開発環境 Eclipse がコピー元の変更をペースト先 の領域に自動的に反映 Concerns view 従来: 多数の機能を言語に導入して解決 言語の学習が困難
コード領域の同期
コード領域の同期 コピー&ペースト
コード領域の同期 updateをredrawに変更
コード領域の同期 updateをredrawに変更 変更が自動で伝わる
Concerns ビュー 同期領域への名前付け Concerns ビューからコピー が可能 コードに名前をつけられる モジュールの再利用が容易
パラメータ化 同期領域のうち部分的に同期しないことも可能 引数を使用場所によって別のものにできる
パラメータの同期 パラメータの同期も可能 同期領域内で同じパラメータを複数回使用できる
デモ1
どのようなパラメータで使用されているか一目でわかる アスペクト抽象 あちこちで同じコードが実行されるとき、どこで実行さ れるかを抽象化(一箇所にまとめる) あちこちで個別にメソッド呼び出ししない aspect Update { pointcut change(Shape s): execution(void Shape+.set*(..)) && this(s); after(Shape s) : change(s) { s.display.update(s); }} コードが実行される場所が一目でわかる class Rectangle extends Shape { int xpos, ypos; int width, height; void setX(int x) { xpos = x; }} どのようなパラメータで使用されているか一目でわかる
Concerns ビューによるアスペクト抽象 コード使用場所の一覧表示 同期の問題点を解消 どこが同期されているのかわかりにくい 意図せず別のコードが書き変わってしまう可能性 パラメータの表示 どのようなパラメータで使用されているのか把握できる
AspectJ との比較 AspectJ の欠点 引数が異なる処理は複数のアスペクトを定義する必要 がある aspect DisplayUpdate { after(Rectangle r) : execution (* *.set*(..)) && this(r) { r.display.update(r.xpos, r.ypos, r.width, r.height); } after(Circle c) : execution (* *.set*(..)) && this(c) { c.display.update(c.centerX-c.r, c.centerY-c.r, 2*c.r, 2*c.r);
カリー化の実現 引数を複数持つ関数に引数を一つ渡すと、残りの引 数を持つ関数を返す def sum(x: Int)(y: Int) = x + y; // カリー化関数の定義(Scala) sum(1)(2) // 3 という演算結果を返す sum(1) // sum(y: Int) = 1 + y という関数を返す
デモ2
カリー化実現の問題点 Concerns ビューではどの引数がパラメータ化され ているかわからない
関連研究 Fluid AOP[Honら ‘06] Linked Editing[Toomimら ‘04] 複数のモジュールにまたがるコードを一度に編集可能 アスペクト指向プログラミングの知識が必要 Linked Editing[Toomimら ‘04] リファクタリング用のツール 既に存在するコードクローンを同時に編集可能 パラメータの同期はできない Concerns ビューに相当する機能はない
まとめ 統合開発環境を活用したモジュール化の提案 対外発表 再利用したいコードを複製し、同期 言語拡張を必要とせず擬似的なアスペクトやカリー化 の実現 対外発表 情報処理学会 第73回全国大会 IDE を活用した言語機構に頼らないコード再利用のためのモ ジュール化 PPL 2011(ポスター)