Skip to content

Latest commit

 

History

History
120 lines (89 loc) · 5.17 KB

File metadata and controls

120 lines (89 loc) · 5.17 KB

Паттерны Фабричный метод и Абстрактная фабрика

Паттерны Фабричный метод и Абстрактная фабрика - порождающие

Фабричный метод определяет интерфейс для создания объекта, но оставляет производным классам решение, какой именно класс инстациировать

Простыми словами, фабричный метод - абстрактная команда, которая может иметь разную реализацию у разных наследников.

Tip

Допустим, существуют норвежский и японский кузнец, каждый из которых делает мечи.
Понятное дело, что норвежский и японский кузнец наследуют от абстрактного класса (интерфейса) кузнец,
а норвежский меч и катана наследуют от абстрактного класса (интерфейса) меч.

В результате кузнец и будет у нас фабрикой по прозводству мечей (продуктов).

Абстрактная же фабрика представляет собой кузнеца, который производит снаряжение - например, шлем, броню и меч (то есть, семейство продуктов).

Таким образом:

  1. Логика создания объектов в отдельном модуле. => Избегается дублирование кода и комфортнее поддержка и модификация.
  2. метод и возвращаемый объект являются абстрактными. => Код становится более гибким, логики проще переключить.
from abc import ABC, abstractmethod


class Sword(ABC):
    def __init__(self, sharpness, length, handle, creator):
        self._sharpness = sharpness
        self._length = length
        self._handle = handle
        self._creator = creator

    @abstractmethod
    def __str__(self, sword_name):
        return "{}. Сделал: {}; Острота: {}; Длина: {}; Рукоять: {}" \
            .format(sword_name, self._creator, self._sharpness, self._length, self._handle)


class NorwegianSword(Sword):
    def __init__(self, sharpness, length, creator):
        handle = "Широкая рукоять"
        super().__init__(sharpness, length, handle, creator)

    def __str__(self):
        return super().__str__("Норвежский меч")


class JapaneseSword(Sword):
    def __init__(self, sharpness, length, creator):
        handle = "Тонкая рукоять"
        super().__init__(sharpness, length, handle, creator)

    def __str__(self):
        return super().__str__("Катана")


class Blacksmith(ABC):
    def __init__(self, name, clothes):
        self._name = name
        self._clothes = clothes

    @abstractmethod
    def __str__(self):
        pass

    @abstractmethod
    def makeSword(self):
        pass


class NorwegianBlacksmith(Blacksmith):
    def __init__(self, name):
        clothes = "Старая рубаха"
        super().__init__(name, clothes)

    def __str__(self):
        return "Норвежский кузнец"

    def makeSword(self):
        self.sword = NorwegianSword("Немного острый", "Короткий", self.__str__())
        return self.sword


class JapaneseBlacksmith(Blacksmith):
    def __init__(self, name):
        clothes = "Аккуратный белый халат"
        super().__init__(name, clothes)

    def __str__(self):
        return "Японский кузнец"

    def makeSword(self):
        self.sword = JapaneseSword("Острый", "Длинный", self.__str__())
        return self.sword

Tip

Теперь, допустим, какой-нибудь заказчик приходит к норвежскому и японскому кузнецу и говорит обоим сделать меч.

Important

ВАЖНО: Заказчик не выбирает, какой меч сделает тот или иной кузнец, и никак повлиять на это не может. Вместо этого заказчик просто дает задание кузнецу сделать меч и потом получает этот меч.

norw_bsm = NorwegianBlacksmith("Сигурд")
norw_sword = norw_bsm.makeSword()
print(norw_sword)


japan_bsm = JapaneseBlacksmith("Харуто")
japan_sword = japan_bsm.makeSword()
print(japan_sword)

# output:
# Норвежский меч. Сделал: Норвежский кузнец; Острота: Немного острый; Длина: Короткий; Рукоять: Широкая рукоять
# Катана. Сделал: Японский кузнец; Острота: Острый; Длина: Длинный; Рукоять: Тонкая рукоять