例題で学ぶデザインパターン #5: デザインパターン〈GoF〉Iterator

例題で学ぶ Jython/Swing デザインパターン《Jython2.5》記事一覧
デザインパターンGoFIterator

《著》越智ことり+小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第1版♪2003/05/23 ● 第2版♪2009/04/03

■ 概要

例題により、アプリケーションを作成する過程を通して、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())

GoFIterator を導入するときに無視できないのが、特殊メソッド __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

》作業中です《

Last updated♪09/06/08