課題B4 (機能理解)

課題B4では, ArgoUMLの図形の選択機能について見ていきます.
具体的には,

「配置された図形がArgoUMLのシステム内部でどのように管理され,選択機能の実行によってどのように取り出されて,どのように選択図形として登録されるか?」
を理解することを目指して, 以下のようにトレースデバッガを操作していきます.
また, ArgoUML内部では, グラフ編集用フレームワークであるGEFが使用されています.
ワークスペース内のargouml-*が、ArgoUMLを構成するプロジェクトであり, GEF-0.13.7がGEFのプロジェクトです。


前準備

課題B3 (接近過程抽出) の終了直後は下図のような状態になっているはずです.

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

ここで, 変数ビュー上の「呼び出し後」のメソッド名が List.get(int) であることを確認してください.
それを確認したら, 変数ビュー上にある「呼び出し後」を開き, 戻り値を右クリックしてください.
右クリックするとポップアップメニューが現れるので, 「オブジェクトの追加時点に飛ぶ」を選択してください.

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


機能理解

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

先ほどの前準備にしたがって進めていくと, 下図のように SelectionManager クラスの addFig(Fig) メソッド内の130行目で一時停止している状態になっているはずです.
このメソッドの仮引数 f が参照している FigClass クラスのインスタンス (id = 1675174935) が, この機能によって選択されるクラス図上の1つの「クラス」に当たります.
この状態になっていれば, ここから時間計測を開始してください. 時間計測はできる限り,1分以内の単位での計測をお願いします.
まずは,「実行時点の登録」ビューの追加ボタンをクリックして実行時点の登録を行ってください.

ここで, ソースコードと変数ビューの List.add(Object) の呼び出し前を見ると, SelectionManager クラスのインスタンス (id = 4310438) のフィールド selections が参照している
ArrayList クラスのインスタンスに, makeSelectionFor(Fig) メソッドの戻り値である SelectionClass クラスのインスタンス (id = 1672744985) が追加されることで,
引数として渡された FigClass クラスのインスタンス (id = 1675174935) が選択状態になることがわかります.
課題B4では, この図形の選択に関わっている SelectionManager クラスのインスタンスと SelectionClass クラスのインスタンス, および FigClass クラスのインスタンスについて見ていきます.
まずは, SelectionClass クラスのインスタンスの方がどこから来たのかを見ていくために,
ステップバックインを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) メソッドに実引数として渡されていた FigClass クラスのインスタンス (id = 1675174935) は,
この SelectionManager クラスの addFig(Fig) メソッド内において, 仮引数 f で渡されてきた値であることがわかります.
ここからは, 配置された図形がArgoUMLのシステム内部でどのように管理されているのかを調べるため,
この 仮引数 f で参照されている 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 に代入されていることがわかります.
ここで, 戻り値がどのようになっているのかを確認するために, ステップインを1回押して, 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() メソッドに入りました.
ここで, 変数ビュー上の this を開くと, この Editor クラスのインスタンス (id = 371019845) のフィールド _layerManager が
LayerManager クラスのインスタンス (id = 1975264229) を参照していることがわかります.
これを確認したら, ステップリターンを1回押して, 呼び出し元に戻ってください.

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

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

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

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

先ほどの結果から, FigClass クラスのインスタンス (id = 1675174935) は, LayerPerspectiveMutable クラスのインスタンス (id = 1248750852) の
contents フィールドが参照している ArrayList のインスタンスによって管理されていることがわかりました.
ここで, ステップオーバーを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は終了です. 時間計測を終了してください.


課題B4の機能理解が終了しましたら, 以下のアンケートにお答えください.

アンケート回答

次へ