第1章 Composite パターン 3/5, IronPython

記事一覧 C#.use(better, IronPython=”WPF”)《IronPython2.6》
# IronPython で学ぶ WPF プログラミングの世界

Composite パターン

《著》本間りす+小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第3版♪2008/04/28

Composite パターンには、いくつの効能があります。ここでは、if/else に象徴される典型的なハードコーディングの問題点を回避するとともに、動的な問題解決が可能になる事例を紹介します。

2a)機能の実現:Composite

Composite::Composite では、複合オブジェクト(合成要素)に固有のプロトコルを規定します。

## --------------------                # Composite::Component            
class FileSystem:
    def __init__(self, name=None):
        self.name = name
        self.size = 0
        self.items = []

    def total(self):
        return reduce(
            lambda acc, e: acc + e.total(),
            self.items,
            self.size)

    def changed(self, client):        
        client.update(
            self.branch(self, 0),
            "%d bytes"%self.total())
    def branch(self, parent, indent):
        s = []
        for child in parent.items:
            s.append("%s+-- %s"%(" "*4*indent, child.name))
            if self._isdir(child):
                s.append(" [%d]\n"%child.total())
                s.append(self.branch(child, indent+1))
            else:
                s.append(" [%d]\n"%child.size)
        return "".join(s)

parent を頂点とする部分木に含まれる情報を、文字列で表現します。部分木を構成する各要素 e によって、適切に処理します。

各要素 e 処理
フォルダー それを頂点とする部分木に含まれる情報を文字列で表現します
ファイル そのサイズ(数値)を文字列で表現します

各 child が、フォルダーかファイルかを判定する必要があるので、コードが複雑になります。Composite パターンを導入すると、この問題を回避して、冗長な if/else の呪縛から解放されるだけでなく、動的な問題解決が可能になります。

《Tips》メンテナンスの悪夢: ハードコーディングの典型である if/else が醜悪なのは、要求仕様の変更に対して脆弱さを露呈することです。そのため、西暦二千年問題と同じ病巣を抱え、メンテナンスの悪夢が蘇ります。この例題では、木構造の文字列表現を提供する場面に登場するだけです。しかし、実際のアプリケーション開発では、提供される機能と同等の if/else が散在することになります。すると、新たなサービスを提供したいときに、これらの散在する箇所をすべて洗い出す必要に駆られ、西暦二千年問題が再燃します。□

    def _isdir(self, node):
        return len(node.items)

node を頂点とする部分木が、子要素 node.items を含むなら、フォルダーと見なします。それ以外なら、ファイルと見なします。

Composite パターンを導入する前に

古典的な Composite パターンを導入する前の状態を示したのが、サンプルファイル dirComposite.py です。


具体的な WPF コントロール(Button/TextBox/Label)に関する情報は、マークアップを使って dirComposite.xaml ファイルの中に封じ込めてあるので、分離コードでは、WPF コントロールに依存しない部分だけを記述するように努めます。
複合オブジェクトは、単一オブジェクトの集合体です。ここでは、FileSystem が、複合/単一オブジェクトを区別せずに、一様に扱います。集合体に含まれる要素 items が空なら、それを単一オブジェクトと見なします。つまり、空要素ならファイルと見なし、それ以外ならフォルダーと見なします。

》こちらに移動中です《
TOP


関連記事

Last updated♪2009/11/20