《Jython2.5》JTree〈GoF〉Iterator を実現する

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

Java プログラマーのための Python 導入ガイド〈初級/応用編〉《Jython2.5》
JTree〈GoFIterator を実現する

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

■ 概要

フォルダー/ファイルの階層構造を「簡単に」閲覧できるツールがあると便利です。

この課題では、Swing/GUI を使って階層構造を持つ情報を提示します。〈GoF〉Composite/Iterator/Visitor/Command パターンを導入すると、if/for 文によるコードの汚染、配列の境界問題が解消されるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。

《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。

事例:コードの解説

イテレーター:__iter__

組み込み関数 iter に呼応して、各要素を参照するイテレーターが得られます。

class Node(object):                             # Composite::Component
    def __iter__(self):
        for e in self.treeNode.children():
            yield e.userObject

メソッド __iter__ の本体では、ビュー DefaultMutableTreeNode から得られる子ノード treeNode.children の情報をもとに、各ノードからモデル e.userObject を参照します。
実現する手段として利用した DefaultMutableTreeNode に依存するコードの断片は、このメソッド内だけに記述されます。すると、以下に示すコードの断片はどれも、それを実現する手段(how)を知る必要がなく、それで実現したい目的(what)に着目して、コードを記述できます。

■ ファイル(フォルダー内)の数

組み込み関数 len に呼応して、フォルダー内に含まれるファイルの数が得られます。

    def __len__(self):
        return reduce(lambda s,e: s+len(e)+1, self, 0)
■ ファイル(フォルダー内)の合計サイズ
class DirNode(Node):                            # Composite::Composite
    def getsize(self):
        return reduce(lambda s,e: s+e.getsize(), self, 0)
■ インデント数(ノードの深さ)

メソッド indents を利用すると、各ノードのインデントを返すイテレーターが得られます。

class DirNode(Node):                            # Composite::Composite
    def indents(self, indent=0):
        return reduce(lambda s,e: s+e.indents(indent+1), self, [indent])
■ テキストによるツリー表示
class DirNode(Node):                            # Composite::Composite
    def textTree(self, indent=0):
        print "*",
        return reduce(
            lambda s,e: s+(e.textTree(indent+1)),
            self,
            ["%s%s%r"%(
                self.tab1*(indent-1), self.tab2*(not not indent), self)])
■ 前順走査

メソッド preorder は、preorderEnumeration と同様に、その傘下にある各ノードを「前順走査」します。

class DirNode(Node):                            # Composite::Composite
    def preorder(self):
        return reduce(lambda s,e: s+e.preorder(), self, [self])

対話モード

実行中の Java アプリケーションの状態は、Jython の対話モードでも確認できます。

>>> m = Xmodel
>>> root = m.view.root; type(root); root

jreload
>>> node = root.userObject; type(node); node
<class '__main__.DirNode'>
jreload

最上位のノード root が保持するオブジェクト node は、ディレクトリー DirNode で、jreload を表現しています。

>>> for i, e in zip(node.indents(), node):
... 	print i, repr(e)
... 
0 jreload
1 _xample
2 Version.class
1 example.jar
1 src
2 example
3 jar-Version.java
3 new-Version.java
3 PrintVer.java

メソッド indents を利用すると、各ノードのインデント(深さ)を表わす数に続いて、その名前が出力されます。


次の段階では、ツリーを表現するために、各インデントに合わせた装飾を施します。

Tips

》作業中です《

Last updated♪2009/07/08