Visitorパターン

概要

データの構造と、それに対する処理を分離する」パターンです。

Pythonでは map()関数や、リスト内包表記でvisitorパターンを実現することができます。

例題

1から5までの数値が入った配列のそれぞれの数値を3倍にするプログラムを書いてみます。

サンプルコード

def main():
    l = [1, 2, 3, 4, 5]
    print(l)

    l2 = [triple(i) for i in l]
    print(l2)


def triple(num):
    return 3 * num


if __name__ == "__main__":
    main()

# 出力

[1, 2, 3, 4, 5] [3, 6, 9, 12, 15]

特徴

リスト内包表記を使用しているのは以下の部分です。

l2 = [triple(i) for i in l]

リスト内包表記はfor文でも同じ挙動のコードを書くことができます。

append文を使用していない分、高速化されるというメリットがあります。

l2 = []
for i in l:
    l2.append(triple(i))

以下では、条件分岐がある場合のリスト内包表記について書きます。

# if文がある場合のリスト内包表記

if文を付与する場合は、 一番最後にif文の条件を書きます

l2 = [triple(i) for i in l if i % 2 == 0]

# if - else 文がある場合のリスト内包表記

if - else文を付与する場合は、 真ん中にif - else文の条件を書きます

l2 = [triple(i) if i % 2 == 0 else i for i in l]

リスト内包表記は実行速度の改善にもつながることのある一方、 特にif-else文などを使用すると可読性が下がることもあるので、状況に応じて使い分けてください。

Pythonらしく書くためのコツ

リスト内包表記によってPythonらしく書くことができます。

クラス図

# 一般的なクラス図

一般的なクラス図(Visitorパターン)

一般的なクラス図でどのような動きをしているかはヌーラボさんのHPがわかりやすいです。

一言でいうと、
ConcreteElement.accept()ConcreteVisitor.visit()を呼び出すことで、共通の処理を実現しています。

# サンプルコードにおけるクラス図

なし

参考URL

Visitor(ビジタ)

pythonの内包表記を少し詳しく

Wikipedia - Visitorパターン