目次
● Factory Method パターン
● Abstract Factory パターン
● Builder パターン
● Singleton パターン
● Prototype パターン
その他のデザインパターン
● Factory Method パターン
FactoryMethod.py
# ---------------------------------------------------------------------------------------
# Factory Method パターン
# ---------------------------------------------------------------------------------------
# オブジェクトを作成するためのインターフェースを定義し、サブクラスが作成する具象クラスを決定します。
from abc import ABCMeta, abstractmethod
# 抽象的な製品
class Payment(metaclass=ABCMeta):
@abstractmethod
def pay(self, money):
pass
# 抽象的な工場
class PaymentFactory(metaclass=ABCMeta):
@abstractmethod
def create_payment(self):
pass
# 具象クラス(製品)
class VisaPay(Payment):
def pay(self, money):
print("Visa支払い:{0}円".format(money))
# 具象クラス(製品)
class MasterPay(Payment):
def pay(self, money):
print("Master支払い:{0}円".format(money))
# 具象クラス(工場)
class VisaFactory(PaymentFactory):
def create_payment(self):
return VisaPay()
# 具象クラス(工場)
class MasterFactory(PaymentFactory):
def create_payment(self):
return MasterPay()
if __name__ == '__main__':
# Client(利用側)
# 利用側は利用されるVisaPayなどに依存しません。
py = VisaFactory()
p = py.create_payment()
p.pay(1000)
py = MasterFactory()
p = py.create_payment()
p.pay(2000)
実行結果:
Visa支払い:1000円
Master支払い:2000円
● Abstract Factory パターン
AbstractFactory.py
# ---------------------------------------------------------------------------------------
# Abstract Factory パターン
# ---------------------------------------------------------------------------------------
# ファクトリクラスインターフェイスを定義し、サブファクトリクラスで互いに関連する一連オブジェクト群を間違いなく作成します。
from abc import ABCMeta, abstractmethod
# 抽象的なCPU
class CPU(metaclass=ABCMeta):
@abstractmethod
def show_cpu(self):
pass
# 抽象的なOS
class OS(metaclass=ABCMeta):
@abstractmethod
def show_os(self):
pass
# 抽象的な工場
class SmartphoneBase(metaclass=ABCMeta):
@abstractmethod
def make_cpu(self):
pass
@abstractmethod
def make_os(self):
pass
# ----------具象CPU--------
class AppleCPU(CPU):
def show_cpu(self):
print("Apple CPU")
class SnapdragonCPU(CPU):
def show_cpu(self):
print("Snapdragon CPU")
# ----------具象OS--------
class IOS(OS):
def show_os(self):
print("IOS モバイルオペレーティングシステム")
class Android(OS):
def show_os(self):
print("Android モバイルオペレーティングシステム")
# ----------具象工場--------
class AppleFactory(SmartphoneBase):
def make_cpu(self):
return AppleCPU()
def make_os(self):
return IOS()
class SamsungFactory(SmartphoneBase):
def make_cpu(self):
return SnapdragonCPU()
def make_os(self):
return Android()
# ------------ Client(利用側) ------------
class Smartphone(object):
def __init__(self, cpu, os):
self.cpu = cpu
self.os = os
def show_info(self):
print("スマートフォン情報:")
self.cpu.show_cpu()
self.os.show_os()
def make_smartphone(factory):
cpu = factory.make_cpu()
os = factory.make_os()
return Smartphone(cpu, os)
if __name__ == '__main__':
p1 = make_smartphone(AppleFactory())
p1.show_info()
p2 = make_smartphone(SamsungFactory())
p2.show_info()
実行結果:
スマートフォン情報:
Apple CPU
IOS モバイルオペレーティングシステム
スマートフォン情報:
Snapdragon CPU
Android モバイルオペレーティングシステム
● Builder パターン
Builder.py
# ---------------------------------------------------------------------------------------
# Builder パターン
# ---------------------------------------------------------------------------------------
# 連鎖呼び出しで、複雑なオブジェクトを段階的に構築します
def return_this(func):
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
return self
return wrapper
class Computer:
def __init__(self):
self.cpu = ''
self.usbCount = 0
self.display = ''
self.builder = Computer.Builder(self)
def show_info(self):
print("cpu: {0}, usbCount: {1}, display: {2}".format(self.cpu, str(self.usbCount), self.display))
# 内部クラス
class Builder:
def __init__(self, computer):
self.cpu = computer.cpu
self.usbCount = computer.usbCount
self.display = computer.display
@return_this
def set_cpu(self, cpu):
self.cpu = cpu
@return_this
def set_usbCount(self, usbCount):
self.usbCount = usbCount
@return_this
def set_display(self, display):
self.display = display
def build(self):
newComputer = Computer()
newComputer.cpu = self.cpu
newComputer.usbCount = self.usbCount
newComputer.display = self.display
newComputer.builder = self
return newComputer
# ------------ Client(利用側) ------------
class Computer001Builder:
def __init__(self):
self.computer = Computer().builder \
.set_cpu("Core i7-6700") \
.set_usbCount(2) \
.set_display("ASUS VZ249HE") \
.build()
def get_computer(self):
return self.computer
if __name__ == '__main__':
print("-----PC製品-----")
c001 = Computer001Builder().get_computer()
c001.show_info()
print("-----自作PC-----")
# デフォルト構成
# 連鎖呼び出しで、PC製品というオブジェクトを段階的に構築します
selfMakeComputer = Computer().builder \
.set_cpu("Core i5-6500") \
.set_usbCount(1) \
.set_display("Dell U2720QM") \
.build()
selfMakeComputer.show_info()
# 構成変更
print("-----自作PCにUSB増設-----")
selfMakeComputer = selfMakeComputer.builder.set_usbCount(5).build()
selfMakeComputer.show_info()
実行結果:
-----PC製品-----
cpu: Core i7-6700, usbCount: 2, display: ASUS VZ249HE
-----自作PC-----
cpu: Core i5-6500, usbCount: 1, display: Dell U2720QM
-----自作PCにUSB増設-----
cpu: Core i5-6500, usbCount: 5, display: Dell U2720QM
● Singleton パターン
Singleton.py
# ---------------------------------------------------------------------------------------
# Singleton パターン
# ---------------------------------------------------------------------------------------
# インスタンスを1つしか生成できないクラスを作成します。
class SingletonBase:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(SingletonBase, cls).__new__(cls)
return cls._instance
class SingletonA(SingletonBase):
def __init__(self, x):
self.x = x
if __name__ == '__main__':
s1 = SingletonA(100)
s2 = SingletonA(300)
print(s1.x)
print(s2.x)
print("s1のアドレス:{0}, s2のアドレス:{1}".format(id(s1), id(s2)))
実行結果:
300
300
s1のアドレス:2060572639088, s2のアドレス:2060572639088
● Prototype パターン
Prototype.py
# ---------------------------------------------------------------------------------------
# Prototype パターン
# ---------------------------------------------------------------------------------------
# オブジェクトを複製します
class ProtoType:
def __init__(self, id, name):
super().__init__()
self.id = id
self.name = name
def clone(self):
import copy
return copy.deepcopy(self)
if __name__ == '__main__':
original = ProtoType(100, "テスト名称")
o_copy = original.clone()
print('original.id: {} original.name: {}'.format(original.id, original.name))
print('o_copy.id: {} o_copy.name: {}'.format(o_copy.id, o_copy.name))
print('オブジェクト(original)のID: {} '.format(id(original)))
print('オブジェクト(o_copy)のID: {} '.format(id(o_copy)))
実行結果:
original.id: 100 original.name: テスト名称
o_copy.id: 100 o_copy.name: テスト名称
オブジェクト(original)のID: 1828390518688
オブジェクト(o_copy)のID: 1828390518208
その他のデザインパターン
Pythonで構造に関するデザインパターンを作成してみた
Pythonで振る舞いに関するデザインパターンを作成してみた