Template Method Figure abstract drawGraphics g draw Figure
Template Methodパターン 親クラスのあるメソッド内で抽象メソッドを呼ぶ Figure abstract draw(Graphics g) draw. Figure() 抽象メソッド ・・・・・・ void draw. Figure(){ g. cleargraphics(); draw(g); ・・・ } 1つ以上のクラスが継承 Circle Rectangle Triangle draw(Graphics g) 抽象メソッドをオーバーライド クラス追加 Figure f 1 f 2 == == new new Circle(); Rectangle(); Figure f 3 = new Triangle(); f 1. draw. Figure(); f 2. draw. Figure(); 異なる処理を f 3. draw. Figure(); 共通のインターフェースで動作 変更範囲を限定することで保守性が向上 特別研究発表会 2009/2/23 3
問題点(2/2) –同時変更の例n 関連するクラス全てを同時に変更する必要がある Figure 変 更 abstract draw(Graphics g) draw. Figure() abstract draw() draw. Figure() Circle Rectangle Triangle draw(Graphics g) 変更 変更 変更 n Figure Circle Rectangle Triangle draw() パターンの適用により同時変更が生じる 特別研究発表会 2009/2/23 5
調査する変更 抽象メソッドのメソッド定義の変更 n 抽象メソッドの数の変更 n Template Methodの消滅 n これらの変更の有無を 調査 Super. Class template. Method() primitive. Operation() template. Method() another. Method() primitive. Operation(int) primitive. Operation 2() Sub. Class 1 Sub. Class 2 primitive. Operation() 変更前 特別研究発表会 Sub. Class 2 Sub. Class 1 primitive. Operation() primitive. Operation(int) Operation 1() primitive. Operation(int) Operation() primitive. Operation 2() 変更後 2009/2/23 8
型名類似度Sim. T メソッド内の一時変数・参照変数の型名と呼び出される メソッドの引数・戻り値の型名の一致割合 Scanner 1クラスのnew. Scannerメソッド protected Scanner new. Scanner() { Zip. Scanner zs = new Zip. Scanner(); zs. set. Encoding(encoding); default. Encoding = false; String return zs; boolean } Scanner 2クラスのnew. Scannerメソッド protected Scanner new. Scanner() { Tar. Scanner zs = new Tar. Scanner(); default. Encoding = false; return zs; boolean } 特別研究発表会 Abstract. Scanner template. Method abstract new. Scanner() T 1 = {boolean, String, Zip. Scanner} T 2 = {boolean, Tar. Scanner} Scanner 1 メトリクス値 new. Scanner() Scanner 2 new. Scanner() Sim. T = = 0. 25 抽象メソッドをオーバーライド メトリクス計測対象となるメソッド 2009/2/23 10
識別子名類似度SimⅠ メソッド内の一時変数・参照変数の識別子名と呼び出されている メソッド名の一致割合(ただし型名は除く) Scanner 1クラスのnew. Scannerメソッド protected Scanner new. Scanner() { Zip. Scanner zs = new Zip. Scanner(); zs. set. Encoding(encoding); default. Encoding = false; return zs; } Scanner 2クラスのnew. Scannerメソッド protected Scanner new. Scanner() { Tar. Scanner zs = new Tar. Scanner(); default. Encoding = false; return zs; } 特別研究発表会 Ⅰ 1 = {default. Encoding, zs, encoding, set. Encoding} Ⅰ 2 = {default. Encoding, zs} メトリクス値 SimⅠ = = 0. 5 2009/2/23 11
結果の分析 n 提案した類似度が低く,変更が生じた例 Fig. Call. Action: : layout. Activations SimⅠ = 0. 0, Sim. T = 0. 0 protected void layout. Activations() { if (!get. Src. Fig. Object(). has. Activations()) { get. Src. Fig. Object(). make. Activation( get. Src. Fig. Object(). get. Object. Node(), (Node) get. Src. Link. Port()); ・・・ } else { ・・・ 処理を記述 } } Fig. Call. Action: : layout. Actions Fig. Link layout. Edge abstract layout. Activations Fig. Call. Action Fig. Return. Action layout. Activations protected void layout. Activations(){ //TODO: Auto-generated method stub } 処理を記述していない n 次のバージョンでTemplate Methodが消滅 処理内容の差異が原因で,Template Methodが消滅 特別研究発表会 2009/2/23 14
変更結果の例 n 子クラスの処理差異が変更の要因となっているか? Sub. Class 1 SimⅠ = 0. 0, Sim. T = 0. 0 protected boolean is. Valid. Element(MBase o){ return o instanceof MAssociation. Role … } Sub. Class 2 protected boolean is. Valid. Element(MBase elem){ return elem instanceof MAssociation … } 引数がObjectに変化 処理差異が変更の要因になっている 特別研究発表会 2009/2/23 23
- Slides: 29