Python 弾丸ツアー #DP: ツリー ... step 4: Visitor::ConcreteVisitor

OOPデザインパターンリファクタリング

Python.use(better); Python 弾丸ツアー #DP: Tkinter/Python
>>> ツリー(階層構造)
step 4: Visitor::ConcreteVisitor
《Python3.1|Jython2.5|IronPython2.6》

《著》小粒ちゃん@湘南組《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/23 ● 第4版♪2010/03/08

step 4: コードの解説

■ Visitor::ConcreteVisitor
## ---------------------------------------- Visitor::ConcreteVisitor
class ConcreteVisitor(Visitor):
    def __init__(self, client):
        self.client = client

 ̄具象クラス ConcreteVisitor では、子孫クラスに共通するプロトコルを規定します。
・メソッド __init__ では、さまざまなインスタンス属性を初期設定します。

class TreeVisitor(ConcreteVisitor):
    def visitLeaf_(self, node, indent):
        tab1 = "    "
        tab2 = "  . "
        self.client.append(
            master=self.client.widget,
            tab=tab1*indent+tab2,
            image=self.client.fileImage,
            node=node,
            )

    def visitComposite_(self, node, indent):
        tab1 = "    "
        tab2 = "  - "
        self.client.append(
            master=self.client.widget,
            tab=tab1*indent+tab2,
            image=self.client.dirImage,
            node=node,
            )
        for e in node:
            e.accept_(TreeVisitor(self.client), indent+1)

 ̄具象クラス TreeVisitor では「コンポーネント」を使ってツリーを表現します。

    def visitLeaf_(self, node, indent):
        ...
        self.client.append(
            master=self.client.widget,
            ...
            image=self.client.fileImage,

 ̄メソッド visitLeaf_ では、末端にあるノード(葉)に対する処理を規定します。

    def visitComposite_(self, node, indent):
        ...
        self.client.append(
            master=self.client.widget,
            ...
            image=self.client.dirImage,
            ...
        for e in node:
            e.accept_(TreeVisitor(self.client), indent+1)

 ̄メソッド visitComposite_ では、中間にあるノード(枝)に対する処理を規定します。node の傘下にある各ノード e(ディレクトリー/ファイル)を巡回しながら、新たに生成した TreeVisitor を容認します。

class TextVisitor(ConcreteVisitor):
    def visitLeaf_(self, node, indent):
        self.client.append(self._item(indent, ". ", node))

    def visitComposite_(self, node, indent):
        self.client.append(self._item(indent, "- ", node))
        for e in node:
            e.accept_(TextVisitor(self.client), indent+1)

    def _item(self, indent, s, node):
        return "\n"+"| "*indent + s + node.item

 ̄具象クラス TextVisitor では「文字列」を使ってツリーを表現します。

    def visitLeaf_(self, node, indent):
        self.client.append(self._item(indent, ". ", node))

 ̄メソッド visitLeaf_ では、中間にあるノード(枝)に対する処理を規定します。

    def visitComposite_(self, node, indent):
        self.client.append(self._item(indent, "- ", node))
        for e in node:
            e.accept_(TextVisitor(self.client), indent+1)

 ̄メソッド visitComposite_ では、中間にあるノード(枝)に対する処理を規定します。node の傘下にある各ノード e(ディレクトリー/ファイル)を巡回しながら、新たに生成した TextVisitor を容認します。□

《Point》各ノードを巡回しながら、Visitor ごとに新たな Visitor を生成します。TreeVisitor では、

        for e in node:
            e.accept_(TreeVisitor(self.client), indent+1)

任意の node を頂点とする部分ツリーの各ノード e を巡回しながら、TreeVisitor を容認 accept_ します。同様に、TextVisitor では、

        for e in node:
            e.accept_(TextVisitor(self.client), indent+1)

任意の node を頂点とする部分ツリーの各ノード e を巡回しながら、TextVisitor を容認 accept_ します。□

TOP
》作業中です《