python: Domain-Driven-Design
domain/
aggregates/
entities/
value objects/
events
application/
services
commands
queries
infrastructure/
repositories
messaging/
tests
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:实体(Entity)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:12
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : Entities.py
# explain : 学习
from uuid import UUID
class Customer:
"""
实体(Entity)
"""
def __init__(self, id: UUID, name: str, email: str):
"""
:param id:
:param name:
:param email:
"""
self.id = id
self.name = name
self.email = email
class Product:
"""
实体(Entity)
"""
def __init__(self, id: UUID, name: str, price: float):
"""
:param id:
:param name:
:param price:
"""
self.id = id
self.name = name
self.price = price
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:值对象(Value Object)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:14
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : ValueObjects.py
# explain : 学习
from dataclasses import dataclass
from Entities import Product
@dataclass(frozen=True)
class Address:
"""
值对象(Value Object)
"""
street: str
city: str
state: str
zip_code: str
@dataclass(frozen=True)
class OrderItem:
"""
值对象(Value Object)
"""
product: Product
quantity: int
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:聚合(Aggregate) 一组相关联的对象,作为一个整体进行操作和事务处理。
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:15
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : Aggregates.py
# explain : 学习
from uuid import UUID
from Entities import Product
from Entities import Customer
from typing import Optional, List
from ValueObjects import OrderItem
from ValueObjects import Address
class Order:
"""
聚合(Aggregate)
"""
def __init__(self, id: UUID, customer: Customer, items: List[OrderItem], shipping_address: Address, discount_rate: float = 0.0):
"""
:param id:
:param customer:
:param items:
:param shipping_address:
:param discount_rate:
"""
self.id = id
self.customer = customer
self.items = items
self.shipping_address = shipping_address
self.discount_rate = discount_rate
def apply_discount(self, discount_rate: float):
"""
:param discount_rate:
:return:
"""
self.discount_rate = discount_rate
def total_price(self) -> float:
"""
:return:
"""
total = sum(item.product.price * item.quantity for item in self.items)
return total * (1 - self.discount_rate)
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:33
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : Event.py
# explain : 学习
from uuid import UUID
from typing import Optional, List
from domain.Entities import Customer
from domain.Entities import Product
class OrderCreated:
"""
"""
def __init__(self, order_id: UUID, customer: Customer):
"""
:param order_id:
:param customer:
"""
self.order_id = order_id
self.customer = customer
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:34
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : EventHandler.py
# explain : 学习
from Event import OrderCreated
class SendOrderConfirmationEmail:
"""
"""
def __init__(self, email_service):
"""
:param email_service:
"""
self._email_service = email_service
def handle(self, event: OrderCreated) -> None:
"""
:param event:
:return:
"""
self._email_service.send(
to=event.customer.email,
subject="Order Confirmation",
body=f"Your order {event.order_id} has been created."
)
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:24
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : RepositoryInterfaces.py
# explain : 学习
from abc import ABC, abstractmethod
from typing import Optional, List
from uuid import UUID
from domain.Entities import Customer
from domain.Entities import Product
from domain.Aggregates import Order
class CustomerRepository(ABC):
"""
"""
@abstractmethod
def save(self, customer: Customer) -> None:
"""
:param customer:
:return:
"""
pass
@abstractmethod
def find_by_id(self, customer_id: UUID) -> Optional[Customer]:
"""
:param customer_id:
:return:
"""
pass
class ProductRepository(ABC):
"""
"""
@abstractmethod
def save(self, product: Product) -> None:
"""
:param product:
:return:
"""
pass
@abstractmethod
def find_by_id(self, product_id: UUID) -> Optional[Product]:
"""
:param product_id:
:return:
"""
pass
@abstractmethod
def find_all(self) -> List[Product]:
"""
:return:
"""
pass
class OrderRepository(ABC):
"""
"""
@abstractmethod
def save(self, order: Order) -> None:
"""
:param order:
:return:
"""
pass
@abstractmethod
def find_by_id(self, order_id: UUID) -> Optional[Order]:
"""
:param order_id:
:return:
"""
pass
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:27
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : RepositoryClasses.py
# explain : 学习
from RepositoryInterfaces import CustomerRepository
from RepositoryInterfaces import ProductRepository
from RepositoryInterfaces import OrderRepository
from uuid import UUID
from typing import Optional, List
from domain.Entities import Customer
from domain.Entities import Product
from domain.Aggregates import Order
class InMemoryCustomerRepository(CustomerRepository):
"""
"""
def __init__(self):
self._store = {}
def save(self, customer: Customer) -> None:
"""
:param customer:
:return:
"""
self._store[customer.id] = customer
def find_by_id(self, customer_id: UUID) -> Optional[Customer]:
"""
:param customer_id:
:return:
"""
return self._store.get(customer_id)
class InMemoryProductRepository(ProductRepository):
"""
"""
def __init__(self):
self._store = {}
def save(self, product: Product) -> None:
"""
:param product:
:return:
"""
self._store[product.id] = product
def find_by_id(self, product_id: UUID) -> Optional[Product]:
"""
:param product_id:
:return:
"""
return self._store
def find_by_id(self, product_id: UUID) -> Optional[Product]:
"""
:param product_id:
:return:
"""
return self._store.get(product_id)
def find_all(self) -> List[Product]:
"""
:return:
"""
return list(self._store.values())
class InMemoryOrderRepository(OrderRepository):
"""
"""
def __init__(self):
self._store = {}
def save(self, order: Order) -> None:
"""
:param order:
:return:
"""
self._store[order.id] = order
def find_by_id(self, order_id: UUID) -> Optional[Order]:
"""
:param order_id:
:return:
"""
return self._store.get(order_id)
# encoding: utf-8
# 版权所有 2024 涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:领域服务(Domain Service)
# Author : geovindu,Geovin Du 涂聚文.
# IDE : PyCharm 2024.3 python 3.11
# os : windows 10
# database : mysql 9.0 sql server 2019, poostgreSQL 17.0
# Datetime : 2024/12/17 20:30
# User : geovindu
# Product : PyCharm
# Project : Pydddsimple
# File : Services.py
# explain : 学习
from uuid import UUID
from typing import Optional, List
from domain.Entities import Customer
from domain.Entities import Product
from domain.Aggregates import Order
from domain.ValueObjects import Address
from domain.ValueObjects import OrderItem
from infrastructure.RepositoryClasses import CustomerRepository
from infrastructure.RepositoryClasses import ProductRepository
from infrastructure.RepositoryClasses import OrderRepository
from domain.Event import OrderCreated
from domain.EventHandler import SendOrderConfirmationEmail
class ECommerceService:
"""
"""
def __init__(self, customer_repository: CustomerRepository, product_repository: ProductRepository, order_repository: OrderRepository):
"""
:param customer_repository:
:param product_repository:
:param order_repository:
"""
self._customer_repository = customer_repository
self._product_repository = product_repository
self._order_repository = order_repository
def create_customer(self, name: str, email: str) -> Customer:
"""
:param name:
:param email:
:return:
"""
customer = Customer(id=UUID(), name=name, email=email)
self._customer_repository.save(customer)
return customer
def create_product(self, name: str, price: float) -> Product:
"""
:param name:
:param price:
:return:
"""
product = Product(id=UUID(), name=name, price=price)
self._product_repository.save(product)
return product
def create_order(self, customer_id: UUID, items: List[OrderItem], shipping_address: Address) -> Order:
"""
:param customer_id:
:param items:
:param shipping_address:
:return:
"""
customer = self._customer_repository.find_by_id(customer_id)
if not customer:
raise ValueError("Customer not found")
order = Order(id=UUID(), customer=customer, items=items, shipping_address=shipping_address)
self._order_repository.save(order)
# Apply discount based on total order value
if order.total_price() > 100:
order.apply_discount(0.1)
# Send email notification (handled by domain event)
event = OrderCreated(order_id=order.id, customer=customer)
SendOrderConfirmationEmail().handle(event)
return order
def get_order_by_id(self, order_id: UUID) -> Optional[Order]:
"""
:param order_id:
:return:
"""
return self._order_repository.find_by_id(order_id)
from:
https://www.w3computing.com/articles/implementing-domain-driven-design-in-python-projects/
https://github.com/heynickc/awesome-ddd
https://github.com/qu3vipon/python-ddd
https://github.com/software-architecture-2030/Domain-Driven-Design-DDD
https://www.geeksforgeeks.org/domain-driven-design-ddd/
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号