参考《设计模式之禅》
from abc import ABC, abstractmethod
class CarModel(ABC):
def __new__(cls, *args, **kwargs):
# 让子类不能覆盖run方法
if cls != cls.__name__ and 'run' in cls.__dict__.keys():
raise Exception('"run" method methond cannot be rewritten')
return super().__new__(cls, *args, **kwargs)
def __init__(self):
self._sequence = []
@abstractmethod
def start(self): pass
@abstractmethod
def stop(self): pass
@abstractmethod
def alarm(self): pass
@abstractmethod
def engine_boom(self): pass
def run(self):
for action_name in self.sequence:
action_name = action_name.lower()
if action_name == 'start':
self.start()
elif action_name == 'stop':
self.stop()
elif action_name == 'alarm':
self.alarm()
elif action_name == 'engine boom':
self.engine_boom()
@property
def sequence(self):
return self._sequence
@sequence.setter
def sequence(self, value):
self._sequence = value
class BMWModel(CarModel):
def start(self):
print("宝马车发动...")
def stop(self):
print("宝马车停车...")
def alarm(self):
print("宝马车鸣笛...")
def engine_boom(self):
print("宝马车引擎声音是这样的...")
class BenzModel(CarModel):
def start(self):
print("奔驰车发动...")
def stop(self):
print("奔驰车停车...")
def alarm(self):
print("奔驰车鸣笛...")
def engine_boom(self):
print("奔驰车引擎声音是这样的...")
class CarBuilder(ABC):
@abstractmethod
def set_sequence(self, sequence): pass
@abstractmethod
def get_car_model(self): pass
class BenzBuilder(CarBuilder):
def __init__(self):
self.benz = BenzModel()
def set_sequence(self, sequence):
self.benz.sequence = sequence
def get_car_model(self):
return self.benz
class BMWBuilder(CarBuilder):
def __init__(self):
self.bmw = BMWModel()
def set_sequence(self, sequence):
self.bmw.sequence = sequence
def get_car_model(self):
return self.bmw
class Director:
def __init__(self):
self.sequence = []
self.benz_builder = BenzBuilder()
self.bmw_builder = BMWBuilder()
def get_benz_model_a(self):
self.sequence.clear()
self.sequence.append('start')
self.sequence.append('stop')
self.benz_builder.set_sequence(self.sequence)
return self.benz_builder.get_car_model()
def get_benz_model_b(self):
self.sequence.clear()
self.sequence.append('engine boom')
self.sequence.append('start')
self.sequence.append('stop')
self.benz_builder.set_sequence(self.sequence)
return self.benz_builder.get_car_model()
def get_bmw_model_c(self):
self.sequence.clear()
self.sequence.append('alarm')
self.sequence.append('start')
self.sequence.append('stop')
self.bmw_builder.set_sequence(self.sequence)
return self.bmw_builder.get_car_model()
if __name__ == '__main__':
sequence = ['engine boom', 'start', 'stop']
benz_builder = BenzBuilder()
benz_builder.set_sequence(sequence)
benz = benz_builder.get_car_model()
benz.run()
bmw_builder = BMWBuilder()
bmw_builder.set_sequence(sequence)
bmw = bmw_builder.get_car_model()
bmw.run()
director = Director()
for i in range(10):
director.get_benz_model_a().run()
for i in range(10):
director.get_benz_model_b().run()
for i in range(10):
director.get_bmw_model_c().run()