例題で学ぶデザインパターン #5: デザインパターン〈GoF〉Iterator
例題で学ぶ Jython/Swing デザインパターン《Jython2.5》《記事一覧》
デザインパターン〈GoF〉Iterator
■ 概要
例題により、アプリケーションを作成する過程を通して、Jython/Swing によるデザインパターンを習得します。
この課題では、Swing/GUI を使って階層構造を持つ情報を提示します。〈GoF〉Composite/Iterator/Visitor/Command パターンを導入すると、if/for 文によるコードの汚染、配列の境界問題が解消されるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。
《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。
事例:モジュールを起動する
モジュールを起動すると、次のようなウィンドウが現れます。
$ jython2.5b3 -i step05/TreeEx.py
ツリー JTree を構成する各ノードを選択すると、その直下にある各項目の名前がテキスト領域 JTextArea に表示されます。たとえば、ノード colors を選択すると、テキスト領域に文字列 blue/violet などが表示されます。
事例:コードの解説
#! /usr/bin/jython2.5b3
class Node(object):
def __init__(self, node, *args, **keys):
self.node = node
def __str__(self):
return "\n".join(map(str, self))
組み込み関数 map を利用すると、第1引数に指定した関数を、第2引数に指定したシーケンス self の各要素に適用した結果が得られます。このとき、self の各要素を順に参照するための仕組みを提供するのが、特殊メソッド __iter__ の役割です。このように簡潔に表現できるのも、__iter__ の効能のひとつです。
■ 特殊メソッド __iter__
def __iter__(self): return iter(self.children())
〈GoF〉Iterator を導入するときに無視できないのが、特殊メソッド __iter__ の存在です。組み込み関数 iter を利用すると、任意の要素を順に参照するためのイテレーターが得られます。
def children(self): s = [self.node] for e in self.node.children(): s += Node(e).children() return s
ツリーのノードの直下にある各ノード e に対して、新たに Node を生成するとともに、メソッド children を適用することで「再帰的な」階層構造に沿った呼び出しが可能になります。
■ 組み込み関数 reduce を使って
def children(self): return reduce( lambda s,e: s+Node(e).children(), self.node.children(), [self.node])
同じ機能は(for 文に代えて)組み込み関数 reduce を使っても実現できます。
Tips
》作業中です《