Python デザインパターン サンプルコード Proxy
結城 浩「Java言語で学ぶデザインパターン入門」をPython化
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-18)Python3.11で動作確認済み
Printable (setPrinterName, getPrinterName, print) ↑ ↑ Printer PrinterProxy (setPrinterName, getPrinterName, print, (setPrinterName, getPrinterName, print, heavyJob) realize)class Printable は,Java サンプルでは interface でありテンプレートです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import time from abc import ABCMeta, abstractmethod from threading import Thread, Lock def synchronized(lock): #Synchronization decorator def wrap(f): def newFunction(*args, **kwargs): lock.acquire() try: return f(*args, **kwargs) finally: lock.release() return newFunction return wrap mylock = Lock() class Printable(metaclass = ABCMeta): @abstractmethod def setPrinterName(self, name): pass @abstractmethod def getPrinterName(self): pass @abstractmethod def printMe(self, string): pass class Printer(Printable): def __init__(self, name): self.name = name self.heavyJob("Printerのインスタンス({})を生成中".format(self.name)) def setPrinterName(self, name): self.name = name def getPrinterName(self): return self.name def printMe(self, string): sys.stdout.write("=== {} ===\n".format(self.name)) sys.stdout.write(string) def heavyJob(self, msg): sys.stdout.write(msg) for i in range(5): try: time.sleep(1) except InterruptedError: pass sys.stdout.write(".") sys.stdout.write("完了。\n") class PrinterProxy(Printable, Thread): def __init__(self, name): Thread.__init__(self) self.name = name self.real = None @synchronized(mylock) def setPrinterName(self, name): if (self.real is not None): self.real.setPrinterName(name) self.name = name def getPrinterName(self): return self.name def printMe(self, string): self.realize() self.real.printMe(string) @synchronized(mylock) def realize(self): if (self.real is None): self.real = Printer(self.name) def main(): p = PrinterProxy("Alice") sys.stdout.write("名前は現在{}です。\n".format(p.getPrinterName())) p.setPrinterName("Bob") sys.stdout.write("名前は現在{}です。\n".format(p.getPrinterName())) p.printMe("Hello, world.") if __name__ == '__main__': main() """標準出力 名前は現在Aliceです。 名前は現在Bobです。 Printerのインスタンス(Bob)を生成中.....完了。 === Bob === Hello, world. """
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#!/usr/bin/env python3 # -*- coding: utf-8 -*- from threading import Thread, Lock import time myLock = Lock() def synchronized(lock): #Synchronization decorator def wrap(f): def newFunction(*args, **kwargs): lock.acquire() try: return f(*args, **kwargs) finally: lock.release() return newFunction return wrap class MyThread(Thread): def __init__(self, n): Thread.__init__(self) self.n = n @synchronized(myLock) def run(self): for i in range(3): print("Thread {}: Start {}...".format(self.n, i)) time.sleep(1) print("Thread {}: Stop {}...".format(self.n, i)) if __name__ == '__main__': threads = [MyThread(i) for i in range(5)] for t in threads: t.start() for t in threads: t.join() """標準出力 Thread 0: Start 0... Thread 0: Stop 0... Thread 0: Start 1... Thread 0: Stop 1... Thread 0: Start 2... Thread 0: Stop 2... Thread 1: Start 0... Thread 1: Stop 0... Thread 1: Start 1... Thread 1: Stop 1... Thread 1: Start 2... Thread 1: Stop 2... Thread 2: Start 0... Thread 2: Stop 0... Thread 2: Start 1... Thread 2: Stop 1... Thread 2: Start 2... Thread 2: Stop 2... Thread 3: Start 0... Thread 3: Stop 0... Thread 3: Start 1... Thread 3: Stop 1... Thread 3: Start 2... Thread 3: Stop 2... Thread 4: Start 0... Thread 4: Stop 0... Thread 4: Start 1... Thread 4: Stop 1... Thread 4: Start 2... Thread 4: Stop 2... # @synchronized(myLock)をコメントアウトしたとき Thread 0: Start 0... Thread 1: Start 0... Thread 2: Start 0... Thread 3: Start 0... Thread 4: Start 0... Thread 2: Stop 0... Thread 2: Start 1... Thread 4: Stop 0... Thread 4: Start 1... Thread 1: Stop 0... Thread 1: Start 1... Thread 3: Stop 0... Thread 3: Start 1... Thread 0: Stop 0... Thread 0: Start 1... Thread 3: Stop 1... Thread 3: Start 2... Thread 1: Stop 1... Thread 1: Start 2... Thread 0: Stop 1... Thread 0: Start 2... Thread 4: Stop 1... Thread 4: Start 2... Thread 2: Stop 1... Thread 2: Start 2... Thread 0: Stop 2... Thread 2: Stop 2... Thread 4: Stop 2... Thread 3: Stop 2... Thread 1: Stop 2... """