Ограниченные контексты (Bounded Contexts) - это ключевая концепция Domain-Driven Design (DDD), которая помогает организовать сложные доменные модели, разделяя их на логические модули с четкими границами.
Bounded Context - это четко определенная граница, внутри которой конкретная доменная модель применяется и остается согласованной. В разных контекстах одни и те же термины могут иметь разное значение.
Примеры на Python
Пример 1: Разные значения в разных контекстах
# Контекст электронной коммерции (E-commerce)
class Product:
def __init__(self, id: str, name: str, price: float, inventory: int):
self.id = id
self.name = name
self.price = price
self.inventory = inventory # Количество на складе
def is_available(self) -> bool:
return self.inventory > 0
# Контекст логистики (Logistics)
class Product:
def __init__(self, id: str, name: str, weight: float, dimensions: tuple):
self.id = id
self.name = name
self.weight = weight # Вес в кг
self.dimensions = dimensions # Габариты (длина, ширина, высота)
def calculate_shipping_cost(self) -> float:
# Логика расчета стоимости доставки
return self.weight * 100 # Упрощенный расчет
Здесь класс Product
имеет разное значение в разных контекстах:
- В e-commerce важны цена и наличие
- В logistics важны вес и габариты
Пример 2: Разделение контекстов с помощью модулей
# Файл: ecommerce/product.py
class Product:
"""Контекст электронной коммерции"""
def __init__(self, id: str, name: str, price: float):
self.id = id
self.name = name
self.price = price
# Файл: logistics/product.py
class Product:
"""Контекст логистики"""
def __init__(self, id: str, weight: float):
self.id = id
self.weight = weight
# Файл: main.py
from ecommerce.product import Product as EcommerceProduct
from logistics.product import Product as LogisticsProduct
# Использование разных контекстов
ecommerce_prod = EcommerceProduct("123", "Laptop", 999.99)
logistics_prod = LogisticsProduct("123", 2.5)
Пример 3: Контекстный маппинг
class ProductMapper:
@staticmethod
def to_ecommerce(logistics_product, price: float) -> "EcommerceProduct":
return EcommerceProduct(
id=logistics_product.id,
name=f"Product {logistics_product.id}", # В реальности это могло бы быть из БД
price=price
)
@staticmethod
def to_logistics(ecommerce_product, weight: float) -> "LogisticsProduct":
return LogisticsProduct(
id=ecommerce_product.id,
weight=weight
)
Ключевые принципы Bounded Context
- Явные границы: Каждый контекст должен иметь четко определенные границы
- Собственный язык (Ubiquitous Language): В каждом контексте свой согласованный язык
- Автономность: Контексты должны быть максимально независимы
- Интеграция: Контексты могут взаимодействовать через антикоррупционные слои (Anti-Corruption Layer)
Когда использовать Bounded Contexts
- Когда модель становится слишком сложной
- Когда разные команды работают над разными частями системы
- Когда одни и те же термины имеют разное значение в разных частях системы
Bounded Contexts помогают управлять сложностью, изолируя разные части системы и позволяя им развиваться независимо.