例題で学ぶデザインパターン #9: デザインパターン Iterator:リファクタリング

前の記事記事一覧次の記事

例題で学ぶ Jython/Swing デザインパターン《Jython2.5》
デザインパターン Iterator リファクタリング

《著》越智ことり+小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第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 step08/TreeEx.py 

 

リファクタリングによって、なにも影響を受けないことが確認できます。

事例:コードの解説

■ モジュール:TreeComposite.py
#! /usr/bin/jython2.5b3

class Node(object):
    ...
    def __iter__(self):
        for e in self.node.children():
            yield e

メソッドの本体に yield 文を記述すると、そのメソッドは「ジェネレータ」になります。たとえば、for 文とともにジェネレータとして Node を利用すると、ツリーを構成する各ノード e が順に得られます。

    def __len__(self):
        return reduce(
            lambda s, e: s + len(Node(e)) + 1,
            self,             # (@.@)
            0)
    def children(self):
        return reduce(
            lambda s, e: s + Node(e).children(),
            self,             # (@.@)
            [self.node])
    def levels(self, level=0):
        return reduce(
            lambda s, e: s + Node(e).levels(level+1),
            self,             # (@.@)
            [level])

リファクタリング後の〈GoFIterator パターンの効能によって、モデル self を指定するだけで、各ノード e を順に参照できます。そして、コンストラクター Node(e) は「再帰的な」階層構造に沿って呼び出されるので、

Tips

》作業中です《

Last updated♪09/06/10