Proxyパターン

概要

代理のオブジェクトを使うことでいろいろメリットがあるパターン」です。

このパターンを使うことで

  • オブジェクトへのアクセス制限
  • オブジェクトの実際の場所に依存しないアクセス
  • オブジェクトの生成の遅延

などを実現することができます。

ここでは、プレーンなProxyパターンを作っていきます。

例題

稟議の仕組みを考えます。

  • 100円の場合は課長も部長もOKを出せます。
  • 3000円の場合は部長しかOKを出せません。
  • 部長は忙しいので、稟議を出すのに時間がかかってしまいます。
  • 起案者(稟議を上げる人)は課長に起案することにします。

サンプルコード

# 承認者 → approver
# 部長 → Director
# 課長 → SectionChief
# としました。
from time import sleep


def main():
    sectionchief = SectionChief()

    print(sectionchief.approve_100yen())   # => OK
    print(sectionchief.approve_3000yen())  # => OK


# Subject
class Approver:
    def approve_100yen(self):
        raise NotImplementedError("abstract method")

    def approve_3000yen(self):
        raise NotImplementedError("abstract method")


# Real subject(主体者)
class Director(Approver):
    def approve_100yen(self):
        sleep(10)
        return "OK"

    def approve_3000yen(self):
        sleep(10)
        return "OK"


# Proxy
class SectionChief(Approver):
    def approve_100yen(self):
        return "OK"

    def approve_3000yen(self):
        return Director().approve_3000yen()


if __name__ == "__main__":
    main()

# 出力

OK OK

2回目のOKは10秒ほど待つと出てきます。

特徴

まず、ユーザー視点から見ていきます。

def main():
    sectionchief = SectionChief()

    print(sectionchief.approve_100yen())   # => OK
    print(sectionchief.approve_3000yen())  # => OK

ユーザーはProxyにrequestを投げるだけでOKです。

次にProxy視点を見ます。

# Proxy
class SectionChief(Approver):
    def approve_100yen(self):
        return "OK"

    def approve_3000yen(self):
        return Director().approve_3000yen()

Proxyはできる仕事は自分で行い(approve_100yen)、
自分にできない仕事(approve_3000yen)はできる人(Real subject; Director)に投げます

こうすることで処理の重いReal subjectの負担を軽減することができます。

Pythonらしい書き方

特になし

クラス図

# 一般的なクラス図

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

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

サンプルコードにおけるクラス図(Proxyパターン)

参考URL

Wikipedia