2010年12月8日水曜日

第21章 Proxyパターン : 必要になってから作る



Proxyパターンもそんなに難しくないですね。RealSubject役がProxy役を意識しないところが味噌ですね。


  • Virtual Proxy ... 今回の例
  • Remote Proxy ... ネットワーク越しのメソッド呼び出しに
  • Access Proxy ... メソッド呼び出しにアクセス制限を設けたい時に




timeモジュールのsleep(sec)はスレッドをブロックするので、マルチスレッド化しなければsynchronizeを意識する必要はなさそうです。

実行結果
名前は現在Aliceです。
名前は現在Bobです。
Printerのインスタンス(Bob)を生成中
生成完了
=== Bob ===
Hello, world

ソースコード
#!/usr/bin/env python
# -*- coding: utf8 -*-

# Subject interface
class __Printable:
    def __init__(self): raise NotImplementedError
    def setPrinterName(self, n): raise NotImplementedError
    def getPrinterName(self): raise NotImplementedError
    def printIt(self): raise NotImplementedError

from time import sleep
# RealSubject class
class Printer(__Printable):
    def __init__(self, name):
        self.__name = name
        print "Printerのインスタンス(%s)を生成中" % name
        self.__heavyjob()

    def getPrinterName(self):
        return self.__name
    def setPrinterName(self, n):
        self.__name = n

    def printIt(self, msg):
        print "=== %s ===" % self.__name
        print msg

    def __heavyjob(self):
        sleep(3)
        print '生成完了'

# Proxy class
class PrinterProxy(__Printable):
    def __init__(self, name):
        self.__name = name
        self.__real = None

    def getPrinterName(self):
        return self.__name
    def setPrinterName(self, n):
        self.__name = n
        if not self.__real == None:
            self.__real.setPrinterName(n)

    def printIt(self, msg):
        if self.__real == None:
            self.__realize()
        self.__real.printIt(msg)


    def __realize(self):
        self.__real = Printer(self.__name)

# Client
def main():
    m_printer = PrinterProxy("Alice")
    print "名前は現在%sです。" % m_printer.getPrinterName()
    m_printer.setPrinterName("Bob")
    print "名前は現在%sです。" % m_printer.getPrinterName()
    m_printer.printIt("Hello, world")

if __name__=='__main__': main()

0 件のコメント:

コメントを投稿