Season II:JTree 篇
■ 概要
アプリケーションを作成する過程を通して、Jython/Swing によるデザインパターンを習得します。
この課題では、Swing/GUI を使って階層構造を持つ情報を提示します。〈GoF〉Composite/Iterator/Visitor/Command パターンを導入すると、if/for 文によるコードの汚染、配列の境界問題が解消されるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。
《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。
Episode
2.00:アプリケーションギャラリー
フォルダー/ファイルの階層構造を「簡単に」閲覧できるツールがあると便利です。
2.01:JTree を利用する
Jython の対話モードを活用すると、実行中のアプリケーションの状態を確認できるので便利です。これらの情報は、Jython の汎用的な機能を利用して得られるので、同等の機能をアプリケーションごとに用意する必要はありません。
02:JTextArea を利用する
JTree のノードを選択すると(値が変更されたときに)メソッド valueChanged が呼び出されるので、発生したイベントから、選択された項目が得られます。
03:リスト、内包、reduce
for 文に代えて、内包や組み込み関数 reduce を使うと、より簡潔に表現できるので便利です。
04:モジュール分割:リファクタリング
リファクタリングの第一歩は、モジュールを分割することです。リファクタリングの前後で、機能は変化しませんが、その後の作業を楽にします。
05:デザインパターン〈GoF〉Iterator
伝統的な while/for で汚染されたコードは、要求仕様に変更があると、その脆弱さを露呈します。その呪縛から逃れるのに〈GoF〉Iterator パターンを導入します。そのときに無視できないのが、特殊メソッド __iter__ の存在です。組み込み関数 iter を利用すると、任意の要素を順に参照するためのイテレーターが得られます。
06:Iterator の効能
〈GoF〉Iterator を導入した効能は、組み込み型、組み込み関数、for 文、内包、ジェネレーター式など、さまざまな要素と融合できることです。
余録:〈GoF〉Iterator を反面教師に
〈GoF〉Iterator を鵜呑みにすると、Jython の特徴を活かせずに損をします。その問題点を指摘するとともに、事例について考察します。特定のプロトコルに依存しなくなると、コードは汚染されなくなります。
07:テキストによるツリー表示
ツリー JTree を構成する各ノードを選択すると、テキスト領域 JTextArea には、その部分ツリーの傘下にある全ノードが表示されます。
09:デザインパターン Iterator:リファクタリング
リファクタリングの効能によって、copy&paste によるコードの汚染と同じ病巣を抱えることなく、重複するコードの断片を削除できます。要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できます。
10:テキストによるツリー表示:仕様変更
伝統的な if/switch で汚染されたコードは、要求仕様に変更があると、その脆弱さを露呈します。その呪縛から逃れるのに〈GoF〉Composite パターンを導入します。
11:JButton を利用する
JButton を選択すると、メソッド actionPerformed が呼び出されるので、新たなウィンドウを開きます。
12:DefaultMutableTreeNode を利用する
JButton を押すと、選択したノードを頂点とする部分ツリーが、新たなウィンドウに表示されます。
14:デザインパターン〈GoF〉Composite, #2
〈GoF〉Composite パターンを導入すると、if/switch が不要になるので、簡潔で見通しの良いコードを記述できるだけでなく、要求仕様の変更にも柔軟に対処できます。データ構造に依存する部分は、特定のメソッドに集約されるので、他のメソッドは実現方法に依存しない抽象表現が可能です。
15:JButton を利用する:仕様変更
仕様変更などにより、新たな機能が必要になるたびに、if 文が追加されます。すると、このモジュールを永遠に閉じられずに「開放閉鎖原則」に背く if 文によって、コードは汚染されます。そこで、この問題を解消するために〈GoF〉Command パターンを導入します。
2.16:デザインパターン〈GoF〉Command
〈GoF〉Command パターンを導入すると、if/switch が不要になるので、簡潔で見通しの良いコードを記述できるだけでなく、要求仕様の変更にも柔軟に対処できます。データ構造に依存する部分は、特定のメソッドに集約されるので、他のメソッドは実現方法に依存しない抽象表現が可能です。特定のプロトコルによってコードが汚染されるのを防ぎます。
》作業中です《