Python

Python デザインパターンを学ぶ Strategyパターン

概要

strategyパターンは、アルゴリズムのロジックとそのインターフェースを分離することが目的。プログラマが、アルゴリズムを使用するための同じインターフェイスを維持しながら、事前に定義されたセットから動的にアルゴリズムを選択したい場合に有効だ。Pythonでは、関数をオブジェクトのプロパティに動的にバインドすることができる。

以下の実装例では、このパターンの実装が非常に簡単であることを示す。

この例では、プログラマは TreeSearch 戦略を提供される。TreeSearch の各インスタンスは任意の種類の search_runner を受け入れ、プログラマは run() メソッドを呼び出して search_runner を実行することができる。これは、特定の search_runner 関数を run() メソッドに動的にバインドすることで実現している。

実装例

コンストラクタには、tree_typeとsearch_runnerを指定する。search_runner は、特定のトラバーサル戦略のアルゴリズムの実装を含む関数。search_runnerが与えられると、それはrunに動的に結び付けられる。runは、選択されたアルゴリズムを呼び出すための一貫したインターフェイスとして機能する。(コンストラクタで search_runner を初期化しなかった場合は、run関数の実装がデフォルトとして使用される。

run_post_order関数、run_in_order関数は、任意のTreeSearchインスタンスの run プロパティに動的にバインドされる関数。これはselfをそのインスタンスへのポインタに置き換え、インスタンスメソッドのように振る舞うことができる。

import types


class TreeSearch:

    def __init__(self, tree_type, search_runner=None):

        self.type = tree_type
        if search_runner:
            self.run = types.MethodType(search_runner, self)

    def run(self):
        print("Running Pre-Order DFS search ", self.type)


def run_post_order(self):
    print("Running Post-Order DFS search ", self.type)


def run_in_order(self):
    print("Running In-Order DFS search ", self.type)


if __name__ == "__main__":

    tree1 = TreeSearch("binary_tree")
    tree1.run()

    tree2 = TreeSearch("run_post_order", run_post_order)
    tree2.run()

    tree3 = TreeSearch("run_in_order", run_in_order)
    tree3.run()