プログラムの織り込み関係を可視化するアウトラインビューの提案と実装 理学部 情報科学科 07_05108 大谷 晃司 指導教員 千葉 滋
オブジェクト指向を用いたソフトウェア開発の問題点 関心事ごとにモジュール化する事が出来ない 図形エディタの再描画処理、タイマー処理など 横断的関心事がクラス間をまたがってしまう Shape Rectangle setX setY setHeight setWidth 代入 代入 代入 代入 GUI GUI GUI GUI 近年、ソフトウェア開発を行う際、オブジェクト指向言語を用いることが多いですが、 オブジェクト指向言語の技術ではモジュール間をまたがってしまい、うまくモジュール化する事の出来ないコードが出てきてしまいます。 例として、図形エディタの再描画処理や、タイマー処理などがあげられます。 下の例を御覧ください。これは図形エディタを作成する際の図形クラスとなっています。 この図のように、Shapeの持っている処理、という視点から見ると、Shapeクラスという形でモジュール化を行う事が出来ます。 Rectangleの持っている処理、という視点から見ても同様にモジュール化を行う事が出来ています。 しかし、GUI処理という関心事の視点から見ると、GUI処理の関心事は、図のようにクラスというモジュール間をまたがってしまいます。 同じように、タイマー処理に対しても、このようにモジュール間をまたがってしまいます。 このようにモジュール間をまたがってしまう関心事を横断的関心事と呼び、 モジュール間をまたがってしまうと、編集や付け外しが困難になってしまうという問題があります。 Timer Timer Timer Timer
アスペクト指向言語で分離 1/3 GluonJ クラス機構の拡張だけでアスペクト指向を実現 横断的関心事を一つのモジュール(リバイザ)にまとめる Shape setX 代入 Timer setY @Reviser class Repainter{ static class ShapeRepainter ex. Shape{ void setX(int x){ super.setX(x); Screen.repaint(); } @Reviser static class RectRepainter ex. Rectangle{ ... Repainter ShapeRepainter setX setY RectangleRepainter setHeight setWidth GUI GUI Rectangle setX 代入 Timer setWidth このような問題を解決するための言語としてアスペクト指向言語が挙げられます。 アスペクト指向言語はオブジェクト指向言語ではうまくモジュール化が行えない横断的関心事を別の機構でモジュール化を行う言語です。 アスペクト指向言語の一つにGluonJという言語が存在します。 GluonJはJavaのクラス機構の拡張だけでアスペクト指向を実現しています。 GluonJの機構であるリバイザを用いて、横断的関心事を一つのモジュールへとまとめる事が出来ます。 図の例では、モジュール間をまたがってしまっていたGUI処理を、このようにRepainterという新しいモジュール、 これをリバイザと呼びますが、このリバイザにまとめることで、モジュール化を達成しています。 GUI GUI 3
アスペクト指向言語で分離 2/3 GluonJ クラス機構の拡張だけでアスペクト指向を実現 横断的関心事を一つのモジュール(リバイザ)にまとめる @Reviserを用いてプログラムの織り込み class Shape{ ... void setX(int x){ this.xPos = x; // Screen.repaint(); } @Reviser class Repainter{ static class ShapeRepainter ex. Shape{ super.setX(x); Screen.repaint(); @Reviser static class RectRepainter ex. Rectangle{ class Rectangle ex.Shape{ void setWidth(int w){ this. width = w; 差分を一つの モジュールにまとめる これが実際のコードです。リバイザを作成するには、クラスの前に@Reviserを付けて織り込みを行いたいクラスを継承し、 メソッドをオーバーライドすることで織り込みを実現します。 このように横断的関心事を一つのモジュールへと分離させることで、編集や処理の付け外しを容易に行う事が出来ます。 タイマー処理などは実際に付け外しを行うことが出てくる為、このように一つのモジュールにまとめて、 付け外しを容易にしておくことが求められます。 4
アスペクト指向言語で分離 3/3 それぞれの横断的関心事をモジュールに分離 Repainter ShapeRepainter setX setY Shape Timer GUI GUI Timer Timer GUI GUI Shape setX 代入 setY Timer ShapeTimer setX setY 同様に、タイマー処理に対してもTimerリバイザというモジュールにまとめると、最終的にはこの図のようになります。 GUI処理はRepainterリバイザにまとめ、タイマー処理はTimerリバイザにまとまめられています。 実行の際にはShapeクラスのsetメソッドに織り込みが行われる為、setメソッドはこのようにGUI処理やタイマー処理と密接な関わりがあります。 逆に、GUI処理をまとめたRepaiterの視点からすると、リバイザは実行の際にメソッドに織り込みを行う為、織り込み対象となるクラス、 この場合ではShapeクラスと密接な関わりがあります。さらに、同じメソッドへ織り込みを行う別のリバイザとも密接な関わりがあります。 Repainter側からするとTimer、Timer側からするとRepainterに当たります。 Shape Repainter Timer Timer
問題:既存のアウトラインビューでは情報不足 分離させたモジュールの情報を知ることが出来ない Repainter ShapeRepainter setX setY GUI Timer GUI Timer Shape Timer GUI GUI Shape setX 代入 setY Timer ShapeTimer setX setY Shape Repainter ここで問題となるのが、既存のアウトラインビューからでは織り込みの情報を得ることが出来ない事です。 横断的関心事をうまく別のモジュールにまとめる事を達成したため、一見よさそうに思われますが、 織り込みが行われるクラスの視点からすると、Shapeのsetメソッドには代入のコードしか書かれていない為、 密接な関わりがあるGUI処理やタイマー処理に対する情報を得ることが出来ません。 また、逆にRepainterやTimer側からも、織り込み対象となるクラスと、同じメソッドへ織り込みを行う別のリバイザの情報を知ることが出来ません。 これらの情報を知るには、プロジェクト内から関連のあるクラスファイルを探し、 実際のコードを探さなければならない為、非常に効率が悪くなってしまいます。 Timer Timer
提案:視点に応じて関連する織り込み情報を提供する アウトラインビュー 提案:視点に応じて関連する織り込み情報を提供する アウトラインビュー 織り込みの情報をそれぞれの視点に応じて提供 GUI Timer GUI Timer Repainter ShapeRepainter setX setY Shape Timer GUI GUI Shape setX 代入 setY Timer ShapeTimer setX setY Shape Repainter そこで、本研究では、視点に応じて関連する織り込み情報を提供するアウトラインビューを提案します。 織り込みの情報をそれぞれの視点に応じて提供する事で、前のページで問題となっていた ShapeクラスからGUI処理やTimer処理などの織り込みの情報が知ることが出来ない、という問題を解決する事が出来ます。 また、RepainterやTimerなどのリバイザ側からも、織り込みの対象となるクラスや、別の織り込みを行うリバイザの存在を知ることが出来ない、 という問題を解決する事が出来ます。 Timer Timer 7
(RepainterリバイザのGUI処理) Shapeから見たアウトラインビュー メソッドの織り込みの順序を階層表示 織り込みの情報をそれぞれの視点に応じて提供 織り込みが行われるクラス (Shape)のアウトラインビュー 織り込みが行われるメソッド (Shapeクラスのsetメソッド) 最初に織り込みを行うメソッド (RepainterリバイザのGUI処理) では、実際にどの様に情報を提供するのかを述べたいと思います。 この図はShapeクラスのアウトラインビューです。実際に織り込みが行われるメソッドに対しては、 織り込みの順序に従って階層表示を行う事で、織り込みの情報を提供します。 赤い枠で囲まれたメソッドが織り込みが行われるShapeクラスのsetメソッドで、 青い枠で囲まれたメソッドが最初に織り込みを行うRepainterリバイザのメソッド、 緑色の枠で囲まれたメソッドが二番目に織り込みを行うTimerリバイザのメソッドとなっています。 このように階層表示を行う事で、織り込みの情報を提供する事が出来ます。 二番目に織り込みを行うメソッド (Timerリバイザのタイマー処理)
Repainterから見たアウトラインビュー メソッドの織り込みの順序を階層表示 織り込みの情報をそれぞれの視点に応じて提供 織り込みを行うリバイザ (Repainter)のアウトラインビュー 織り込みが行われるメソッド (Shapeクラスのsetメソッド) 最初に織り込みを行うメソッド (RepainterリバイザのGUI処理) こちらは織り込みを行うRepainterリバイザのアウトラインビューです。 先ほどと同じように、赤い枠で囲まれたメソッドが織り込みが行われるShapeクラスのsetメソッドで、 青い枠で囲まれたメソッドが最初に織り込みを行うRepainterリバイザのメソッド、 緑色の枠で囲まれたメソッドが二番目に織り込みを行うTimerリバイザのメソッドとなっています。 Shapeクラスと同じように織り込み情報を提供する事で、Repainterからも織り込みの情報を知ることが出来ます。 二番目に織り込みを行うメソッド (Timerリバイザのタイマー処理)
現在の実装 Eclipseプラグインとして開発 Eclipseのコードを読んだ量:約10000行 コード量:約2000行 JDT(Java Development Tools)のアウトラインビューを拡張 実行時に織り込みが行われるメソッドを列挙 前のページで挙げたアウトラインビューの提案を実現する為に、現在実装を進めています。 ここでは現在の実装について述べさせていただきます。 本研究はEclipseのプラグインとして開発し、Java開発支援ツールであるJDTのアウトラインビューを拡張することで実装を行っています。 現時点での実装では、実行時に織り込みが行われるメソッドをすべて列挙するアウトラインビューを実現し、 既存のアウトラインビューとの切り替えを行うよう実装を行いました。 コード量としては、既存のJDTのコードを10,000行程読んだ上で、自分で書き加えたコードがおよそ2000行となっています。
織り込み順のあいまいさ検出 織り込み順で全体の挙動が変わる @Require 本システムが検出 各リバイザの織り込み順の優先順位を指定 @Reviser @Require(Timer.class) class Repainter { … } @Reviser @Require(Repainter.class) class Timer { … } 優先順位を指定しない Timerを先に適用 順序があいまい Repainterを先に適用 優先順位を指定しない 矛盾 実行時に複数のリバイザを織り込む際には、織り込みを行う順番で全体の挙動が大きく変わってしまいます。 そのため、優先順位を指定するために、GluonJには@Requireというアノテーションがあります。 これにより各リバイザの織り込み順の優先順位を指定します。 本システムでは、GluonJの開発環境を支援するツールとして提供する事を 目的としている為、この優先順位のあいまいさの検出も行っています。 この図のように矛盾があったり、優先順位を指定せず、順序があいまいであった場合には エラーとして、この図のようにメソッドの色を変えて表示を行うよう実装しました。 エラー箇所を 色を変えて表示
デモ 実際に本システムを実装したアウトラインビューをお見 せします では、実際に本システムを使用したデモをお見せいたします。
関連研究 AJDT(AspectJ Development Tools)[The Eclipse Foundation] アスペクトの視点から、他のアスペクトの情報を知ることがで きない Code Bubbles[Andrew ら ‘10] 視点によって表示する内容を変更 エディタ(bubble)で表示 Shape setX 代入 setY GUI Timer Repainter ShapeRepainter setX setY GUI Shape Timer 関連研究です。 一つ目はアスペクト指向言語の一つであるAspectJでの開発を支援するAJDTです。 AJDTにはAspectJでの開発を支援するツールが多数提供されています。 AJDTのツールを用いる事で、図のようにShapeクラスからRepainterとTimerの織り込みの情報を知ることが出来ますが、 Repainterからは、Shapeクラスへの織り込みを行うという情報のみで、Timerの存在を知ることは出来ません。 二つ目の関連研究はCode Bubbleです。 Code Bubbleはファイル単位ではなく、メソッドやフィールドなど関心のある情報のみをbubbleとして表示するIDEを開発しています。 Code Bubbleはエディタ(bubble)によって提供しますが、視点を切り替えて表示を行うという点が類似しているため、関連研究としてあげました。
まとめと今後の課題 まとめ 今後の課題 プログラムの織り込み関係を表示するアウトラインビュー 視点に応じて切り替える Eclipseプラグインとして開発 今後の課題 GluonJ開発を支援するツールとして完成 評価 実際に使用してもらい、ビューの切り替えを行う回数を調べる まとめと今後の課題です。 本研究では、プログラムの織り込み関係を表示するアウトラインビューを提案し、 視点に応じて切り替えが行えるアウトラインビューをEclipseのプラグインとして開発しました。 今後の課題としては、本研究で提案した実装を終え、GluonJ開発を支援するツールとして完成させる事です。 また、評価として、実際にプログラマに使用してもらい、本システムでのビューの切り替えを行う回数を調べる事で評価を行いたいと考えています。