Builderパターン(4) Builderの再利用
『Rubyによるデザインパターン』(ラス・オルセン著 ピアソン・エデュケーション刊)の例をPythonに変換して書いています。目次
- Builderパターン(1)
- Builderパターン(2) ポリモーフィックなBuilder
- Builderパターン(3) Builderでオブジェクトの妥当性を保証する
- Builderパターン(4) Builderの再利用
Builderを1回作ったら、そのBuilderを何回も使って、オブジェクトを量産する事ができます。
しかし、以前作ったComputerBuilderでは、コンピュータを量産できません。
class ComputerBuilder(object): def __init__(self): self._computer = Computer() (中略) def computer(self): return self._computer
最初に1個、Computerを作り、それを直接変更しているからです。従って、ComputerBuilder.computer() を何度呼んでも、同一インスタンスが返されてきます。
これを避けるには、ディスプレイの種類・メモリサイズ・ドライブ等の情報を、Builder自身が保持し、
本当のComputerを作るのは、ComputerBuilder.__init__
ではなく、ComputerBuilder.computer
の中、という風にする必要があります。
class ComputerBuilder(object): def __init__(self): self._display = "crt" self._has_turbo_cpu = False self._memory_size=1024 self._drives_args = [] def set_turbo(self, has_turbo_cpu=True): self._has_turbo_cpu = has_turbo_cpu def set_display(self, display): self._display = display def set_memory_size(self, size_in_mb): self._memory_size = size_in_mb def add_cd(self, writable=False): self._drives_args.append(("cd", 760, writable)) def add_dvd(self, writable=False): self._drives_args.append(("dvd", 4000, writable)) def add_harddisk(self, size_in_mb): self._drives_args.append(("harddisk", size_in_mb, True)) def computer(self): if self._has_turbo_cpu: cpu = TurboCPU() else: cpu = BasicCPU() motherboard = Motherboard(cpu, self._memory_size) drives = [] for type, size, writable in self._drives_args: drives.append(Drive(type, size, writable)) return Computer(self._display, motherboard, drives)