Паттерн Строитель - порождающий.
Позволяет создавать сложные объекты пошагово.
Разбиваем объект на детали, каждый строитель делает свои детали по-своему.
Детали можно миксовать (как один из вариантов развития паттерна).
Tip
Допустим, у нас будет строитель собаки и осьминога.
У каждого из них одинаковые функции этапов
(так как оба они наследуются от общего интерфейса Строитель Животных).
Директор получает какого-то строителя (он не знает, какого)
и по очереди вызывает все этапы, в конечном итоге формируя продукт.
from abc import ABC, abstractmethod
class Animal(ABC):
body: str
head: str
legs: str
@abstractmethod
def __str__(self, name):
return "{}. Голова: {}. Тело: {}. Ноги: {}.".format(name, self.head, self.body, self.legs)
class AnimalBuilder(ABC):
@abstractmethod
def add_body(self):
pass
@abstractmethod
def add_head(self):
pass
@abstractmethod
def add_legs(self):
pass
@abstractmethod
def get_result(self) -> Animal:
pass
class Octopus(Animal):
def __str__(self):
return super().__str__("Осьминог")
class OctopusBuilder(AnimalBuilder):
def __init__(self):
self.octopus = Octopus()
def add_body(self):
self.octopus.body = "Слизское тело"
return self
def add_head(self):
self.octopus.head = "Голова осьминога"
return self
def add_legs(self):
self.octopus.legs = "8 ног"
return self
def get_result(self) -> Animal:
return self.octopus
class Dog(Animal):
def __str__(self):
return super().__str__("Собака")
class DogBuilder(AnimalBuilder):
def __init__(self):
self.dog = Dog()
def add_body(self):
self.dog.body = "Мягкое тело"
return self
def add_head(self):
self.dog.head = "Голова собаки"
return self
def add_legs(self):
self.dog.legs = "4 ноги"
return self
def get_result(self) -> Animal:
return self.dogВАЖНО: Директор не знает, какого строителя он заставляет делать этапы и сам продукт в конечном итоге.
Директор просто вызывает этапы, необходимые для создания продукта. Сама логика создания продукта выносится в отдельные строители.
class Director:
_builder: AnimalBuilder
def set_builder(self, builder):
self._builder = builder
def make(self):
self._builder.add_body() \
.add_head() \
.add_legs()
def get_result(self):
return self._builder.get_result()
director = Director()
octopus_builder = OctopusBuilder()
director.set_builder(octopus_builder)
director.make()
octopus: Animal = director.get_result()
print(octopus)
dog_builder = DogBuilder()
director.set_builder(dog_builder)
director.make()
dog: Animal = director.get_result()
print(dog)
# output:
# Осьминог. Голова: Голова осьминога. Тело: Слизское тело. Ноги: 8 ног.
# Собака. Голова: Голова собаки. Тело: Мягкое тело. Ноги: 4 ноги.