Prototypeパターンとは
(概要)
Prototpyeとは、原型や試作品を表す。
Prototpyeパターンでは、あるインスタンスから同じクラスのインスタンスのクローンを
作成するデザインパターンである。
(目的)
あるインスタンスから同じインスタンスのコピーを作成して、複製作業を簡単にできるようにする。
(仕組み)
インターフェース(抽象クラス)にて、複製するオブジェクトの骨組みを作成する
複製したいクラスはインターフェースを継承する
複製したい状態でクラスを登録して、必要に応じて複製を作成する。
(構成要素)
Prototype : 複製するオブジェクトの構成要素(設計図)を定義するインターフェース
ConcretePrototype : Prototypeを具体化したクラス(複製作成する)
Manager : ConcretePrototypeを登録し複製を作成するクラス
Copyモジュール(pythonの標準モジュール):オブジェクトのコピーを作成する関数(deepcopy)を提供
pythonサンプルコード
prototypeパターンのpythonサンプルコード
# prototype.py
from abc import ABC, abstractmethod
from copy import deepcopy
class Prototype(ABC):
@abstractmethod
def use(self, msg):
pass
@abstractmethod
def _clone(self):
pass
class MessageBox(Prototype):
""" Prototypeを継承した、ConcretePrototype """
def __init__(self, decoration_char):
self.__decoration_char = decoration_char
def use(self, msg):
str_msg = str(msg)
print(self.__decoration_char * (len(str_msg) + 4))
print(self.__decoration_char + ' ' + str_msg + self.__decoration_char)
print(self.__decoration_char * (len(str_msg) + 4))
def _clone(self):
print('Copy and Create MessageBox Clone')
return deepcopy(self)
@property
def decoration_char(self):
return self.__decoration_char
@decoration_char.setter
def decoration_char(self, decoration_char):
self.__decoration_char = decoration_char
class UnderLinePen(Prototype):
def __init__(self, underline_char):
self.__underline_char = underline_char
def use(self, msg):
str_msg = str(msg)
print(str_msg)
print(self.__underline_char * len(str_msg))
def _clone(self):
print('Copy and Create UnderlinePen Clone')
return deepcopy(self)
@property
def underline_char(self):
return self.__underline_char
@underline_char.setter
def underline_char(self, underline_char):
self.__underline_char = underline_char
class Manager(object):
def __init__(self):
self.__products = {}
def register(self, name, prototype: Prototype):
self.__products[name] = deepcopy(prototype)
def create_product(self, name):
# 辞書型のproductsから nameキーに一致するproductオブジェクトを取得
product = self.__products.get(name)
# 取得したオブジェクトのクローンメソッドを呼び出してクローンを作成する
return product._clone()
if __name__ == '__main__':
# Managerをそのままインスタンス化する
manager = Manager()
# 各インスタンスの初期設定を作成
m_box = MessageBox('*')
m_box.use('Hello Box')
u_pen = UnderLinePen('-')
u_pen.use('Hello Pen')
# managerに、初期設定の各インスタンスを名前をつけて登録する
manager.register('message_box', m_box)
manager.register('underline_pen', u_pen)
print('')
# Managerを用いて新しいインスタンスを作成すると、初期設定のクローンで新しいインスタンスが作成できる。
new_m_box = manager.create_product('message_box')
new_m_box.use('New Box')
new_u_pen = manager.create_product('underline_pen')
new_u_pen.use('New Pen')
print('')
# 作成された個別のm_boxの設定を変えた場合の影響。manager登録時の設定には影響しない。
m_box.decoration_char = '-'
m_box.use('Hello m_box2')
m_box_clone = manager.create_product('message_box')
m_box_clone.use('Hello m_box_clone') #初期設定の*のまま