Перейти к содержанию

Спецификация

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

Паттерн часто используется в контексте domain driven design.

Реализация

Допустим, имеем класс товара:

@dataclass
class Product:
    price: float
    name: str
    quantity: int
    visible: bool

Делаем базовый класс спецификации:

class Specification(ABC):

    def is_satisfied_by(self, candidate: Product) -> bool:
        ...
Например, наша цель проверить, можно ли купить товар. Для этого нам надо проверять, является ли товар видимым и остался ли он на складе. Сделаем спецификации для этого.

Спецификация для проверки, видимый ли товар:

class IsProductVisibleSpecification(Specification):

    def is_satisfied_by(self, candidate: Product) -> bool:
        return candidate.visible

А теперь спецификация для проверки, остались ли ещё товары:

class IsProductIsAvailableSpecification(Specification):

    def is_satisfied_by(self, candidate: Product) -> bool:
        return candidate.quantity > 0

Теперь эти 2 спецификации мы можем объеденить в одну:

class IsProductIsAvailableForPurchase(Specification):

    def __init__(self):
        self._is_visible = IsProductVisibleSpecification()
        self._is_available = IsProductIsAvailableSpecification()

    def is_satisfied_by(self, candidate: Product) -> bool:
        return self._is_visible.is_satisfied_by(candidate) and self._is_available.is_satisfied_by(candidate)

И проверить:

spec = IsProductIsAvailableForPurchase()
product = Product(price=10, name="A", quantity=10, visible=True)
spec.is_satisfied_by(product) # True

Ссылки