課題B4 (アーキテクチャ理解)

課題B4では, ArgoUMLの図形の選択機能について見ていきます.
ArgoUMLはオープンソースのUMLモデリングツールで, Javaで書かれております.
また, ArgoUML内部では, グラフ編集用フレームワークであるGEFが使用されています.
ワークスペース内のargouml-*が、ArgoUMLを構成するプロジェクトであり, GEF-0.13.7がGEFのプロジェクトです。


前準備

課題B3が終了した直後は下図のような状態になっているはずです.

ここで, ステップバックオーバーを1回押してから, ステップオーバーを1回押してください.
すると, 下図のように363行目に入った直後の状態になるので, そこから続けてステップネクストを3回押してください.

ステップネクストを3回実行すると, selections の get() メソッドの呼び出し直後に実行時点が変わっているはずです.
ここで, 変数ビュー上にある「呼び出し後」を開き, 戻り値を右クリックしてください.
右クリックするとポップアップメニューが現れるので, 「オブジェクトの追加時点に飛ぶ」を選択してください.

「オブジェクトの追加時点に飛ぶ」を選択すると, selections に この SelectionClass クラスが追加された時点である
SelectionManager クラスの addFig(Fig) メソッドの130行目にまで現在の実行時点が遡ります.
下図の状態になっていれば前準備は終了です.


アーキテクチャ理解

Fig クラスはグラフィックエディタ上の図形を表すGEFの内部のクラスです.
また, FigClass クラスはクラス図上に配置された「クラス」を表す ArgoUML のクラスで, Fig クラスの子孫クラスにあたります.
現在の実行時点の行は、図形を選択するたびに実行されます.

先ほどの前準備にしたがって進めていくと, 下図のように SelectionManager クラスの addFig(Fig) メソッド内の130行目で一時停止している状態になっているはずです.
この状態になっていれば, ここから時間計測を開始してください.
まずは,「実行時点の登録」ビューの追加ボタンをクリックして実行時点の登録を行ってください.

ここで, ソースコードと変数ビューを見ると, SelectionManager クラスのインスタンス (id = 4310438) が参照するフィールド selections へは
makeSelectionFor(Fig) メソッドの戻り値である SelectionClass クラスのインスタンス (id = 1672744985) が追加されていることがわかります.
課題B4では, このオブジェクトの追加に関わっている SelectionManager クラスのインスタンスと SelectionClass クラスのインスタンスについて見ていきます.
まずは, SelectioClass クラスのインスタンスの方がどこから来たのかを見ていくために,
ステップバックインを1回押して SelectionManager クラスの makeSelectionFor(Fig) メソッドの中に後ろから入ってください.

SelectionManager クラスの makeSelectionFor(Fig) メソッドの1131行目に入ってきました.
ソースコードを見ると, return customSelection でローカル変数 customSelection が参照する値が返されていることがわかります.

この値がどこから来ているのかを見るために, ステップバックオーバーを1回押して1129行目に戻ってください.
1129行目では 仮引数 f で参照されているインスタンスに対して makeSelection() メソッドが呼び出され,
その戻り値がローカル変数 customSelection に代入されていることが確認できます.
ここで, ステップインを1回押してこのメソッドの中に前から入ってください.

FigClass クラスの makeSelection() メソッドに入りました.
ここでは new SelectionClass(this) で 自分自身を引数に渡して SelectionClass クラスが生成されており,
生成された SelectionClass クラスのインスタンスは 引数で渡された FigClass クラスのインスタンス (id = 1675174935) を参照していることがわかります.
これを確認したら, 呼び出しスタック上で2つ呼び出し元である SelectionManager クラスの addFig(Fig) メソッドをクリックしてください.

現在は SelectionManager クラスの addFig(Fig) メソッドの130行目を見ています.
ここで, ソースコードを見ると, 先ほどの makeSelectionFor(Fig) メソッドには, 仮引数 f で参照されている
FigClass クラスのインスタンス (id = 1675174935) が渡されていることが確認できます.
ここからは, この FigClass クラスのインスタンス (id = 1675174935) がどこから来たのかを見ていきます.
呼び出しスタック上で1つ呼び出し元である SelectionManager クラスの select(Fig) メソッドをクリックしてください.

現在は 呼び出し元である SelectionManager クラスの select(Fig) メソッドの180行目を見ています.
ここで, ソースコードを見ると, 呼び出し先の addFig(Fig) メソッドには 仮引数 f の値が実引数として渡されていることが確認できます.
これを確認したら, 呼び出しスタック上でさらに1つ呼び出し元である ModeSelect クラスの mousePressed(MouseEvent) メソッドをクリックしてください.

呼び出し元である ModeSelect クラスの mousePressed(MouseEvent) メソッドの187行に戻ってきました.
ここで, ソースコードを見ると, 呼び出し先である SelectinoManager クラスの select(Fig) メソッドには
ローカル変数 underMouse の値が実引数として渡されていたことがわかります.

この underMouse の値がどこから来たのかを見るために, ステップバックオーバーを8回押して163行目まで戻ってください.
163行目では, ローカル変数 underMouse が参照するインスタンスが FigGroup にキャストされたあと,
それに対して deepSelect(Rectangle) メソッドが呼び出され, その戻り値が改めて underMouse に代入されていることがわかります.
ここで, 戻り値がどのようになっているのかを確認するために, FigGroup クラスの deepSelect(Rectangle) メソッドの中に前から入ってください.

FigGroup クラスの deepSelect(Rectangle) メソッドに入りました.
すると, deepSelect(Rectangle) メソッドの中では return this で自分自身を戻り値として返していることがわかります.
これを確認したら, ステップバックリターンを1回押して呼び出し元に戻ってください.

ModeSelect クラスの mousePressed(MouseEvent) メソッドの163行目に戻ってきました.
underMouse の値がどこから来ているのかを見るために, ステップバックオーバーを1回押して160行目に戻ってください.
160行目では Editor クラスの hit(Point) メソッドが呼び出され, その戻り値がローカル変数 underMouse に代入されていることが確認できます.
ここで, ステップインを1回押してこのメソッドの中に前から入ってください.

Editor クラスの hit(Point) メソッドに入りました.
ここでは, ステップオーバーを1回実行したあとに, ステップインを2回押して hit(Rectangle) メソッドの中に前から入ってください.

Editor クラスの hit(Rectangle) メソッドに入りました.
ここでは, ステップインを2回押して getLayerManager() メソッドの中に前から入ってください.

Editor クラスの getLayerManager() メソッドに入りました.
ここでは, return _layerManager で LayerManager クラスのインスタンスが返されていることが確認でき,
変数ビュー上の this を開くと, このEditor クラスのインスタンス (id = 371019845) がフィールド _layerManager として
LayerManager クラスのインスタンス (id = 1975264229) を参照していることがわかります.
これを確認したら, ステップリターンで呼び出し元に戻ってください.

Editor クラスの hit(Rectangle) メソッドに戻ってきました.
次は, ステップインで LayerManager クラスの hit(Rectangle) メソッドの中に前から入ってください.

LayerManager クラスの hit(Rectangle) メソッドの中に入りました.
ここで, 変数ビューを確認すると, この LayerManager クラスのインスタンス (id = 1975264229) は,
フィールド _activeLayer として LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) を参照していることがわかります.
また, ソースコードを見ると, このフィールド _activeLayer が参照しているインスタンスに対して hit(Rectangle) メソッドが呼び出されていることが確認できます.
ここでは, ステップインを4回押してこのメソッドの中に前から入ってください.

LayerPerspectiveMutable クラスの hit(Rectangle) メソッドに入りました.
ここで, ソースコードを見ると, 231行目で LayerPerspectiveMutable クラスのインスタンスの
フィールド contents から get() メソッドで Fig クラスのインスタンスを取得していることが確認できます.

取得している値を確認するために, ステップオーバーを2回押して232行目まで進んでください.
232行目まで進んだら, 変数ビュー上の「呼び出し後」を開くと, 戻り値として FigClass クラスのインスタンス (id = 1675174935) が返されていることが確認でき,
したがって, このインスタンスは LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) がリスト内の要素として参照していることがわかります.

先ほどの結果から, FigClass クラスのインスタンス (id = 1675174935) は
LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) が参照していることがわかりました.
ここで, ステップオーバーを1回押して, 実行時点が return f に止まることを確認してください.
これを確認したら, 呼び出しスタック上で4つ呼び出し元である ModeSelect クラスの mousePressed(MouseEvent) メソッドをクリックしてください.

現在は, ModeSelect クラスの mousePressed(MouseEvent) メソッドを見ています.
ここで, 変数ビュー上で this を開くと, Editor クラスのインスタンス (id = 371019845) は
ModeSelect クラスのインスタンス (id = 1807431709) が フィールド editor として参照していることがわかります.

ここまでの結果から, SelectionClass クラスのインスタンスに関わる各オブジェクトの関係について, 以下のことがわかりました.

  1. SelectionClass クラスのインスタンス (id = 1672744985) は Fig クラスのインスタンス (id = 1675174935) を引数に渡して生成している.
  2. FigClass クラスのインスタンス (id = 1675174935) は LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) が参照している.
  3. LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) は LayerManager クラスのインスタンス (id = 1975264229) が参照している.
  4. LayerManager クラスのインスタンス (id = 1975264229) は Editor クラスのインスタンス (id = 371019845) が参照している.
  5. Editor クラスのインスタンス (id = 371019845) は ModeSelect クラスのインスタンス (id = 1807431709) が参照している.
課題B4では, オブジェクトの追加に関わっている SelectionManager クラスのインスタンスと SelectionClass クラスのインスタンスについて見ていくのでした.
ここからは, SelectionManager クラスのインスタンスの方がどこから来たかを見ていきます.
まずは, ステップバックオーバーを1回押して156行目に戻ってください.
ソースコードを見ると, Editor クラスの getSelectionManager() メソッドの戻り値がローカル変数 sm に代入されていることがわかります.
ここで, ステップインを1回押して このメソッドの中に前から入ってください.

Editor クラスの getSelectionManager() メソッドに入りました.
ここで, 変数ビュー上の thisを開くと, Editor クラスのインスタンス (id = 371019845) が フィールド _selectionManager として
SelectionManager クラスのインスタンス (id = 4310438) を参照していることがわかります.

先ほどの結果から, SelectionManager クラスのインスタンス (id = 4310438) は
Editor クラスのインスタンス (id = 371019845) が参照していることがわかりました.
呼び出しスタック上で1つ呼び出し元である ModeSelect クラスの mousePressed(MouseEvent) メソッドをクリックしてください.
ここで, 課題B4は終了です. 時間計測を終了してください.