Skip to content

Latest commit

 

History

History
139 lines (98 loc) · 3.8 KB

File metadata and controls

139 lines (98 loc) · 3.8 KB

Паттерн Строитель

Паттерн Строитель - порождающий.

Позволяет создавать сложные объекты пошагово.

Разбиваем объект на детали, каждый строитель делает свои детали по-своему.

Детали можно миксовать (как один из вариантов развития паттерна).

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 ноги.