python: Domain-Driven-Design

 

 

domain/
  aggregates/
  entities/
  value objects/
  events
application/
  services
  commands
  queries
infrastructure/
  repositories
  messaging/
tests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 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

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 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

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 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)

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 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

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 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."
        )

  

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# 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

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# 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)

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# 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/

 

posted @   ®Geovin Du Dream Park™  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2023-12-17 Python: Random
2023-12-17 Enum in Python,Java,CSharp
2022-12-17 CSharp: Chain of Responsibility Pattern in donet core 6
2022-12-17 CSharp: Proxy Pattern in donet.core 6.0
2022-12-17 python: qrcode
2021-12-17 java: MySql Connection using JDK 14.02
2021-12-17 java: Lamdba
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示