DDD example python

- 6 mins

Bài viết sẽ review qua về domain driven design và clean architecture là 2 concept quan trọng khi lập trình

DDD - Domain driven design

Đây là một cách tiếp cận code (concept, quy tắc) một ứng dụng dựa vào phát triển các model liên quan đến domain của bài toán cần giải quyết.

Clean architecture

Clean architecture là một SA pattern sử dụng để thiết kế chương trình dễ maintain, test, mở rộng khi ứng dụng phát triển thêm yêu cầu. Mỗi layer trong pattern này có trách nhiệm riêng nhưng thường được chia làm 3 phần chính:

Ưu điểm của DDD và Client architecture

DDD concepts

DDD đặt domain model làm trung tâm của chương trình. Tất cả các thành phần khác trong chương trình được thiết kế để phục vụ cho các model. Concept của DDD bao gồm:

So sánh DDD và Client architecture

DDD là một kĩ thuật tập trung phát triển code dựa vào domain model, liên quan đến business, trong khi client architecture là một pattern hướng đến giảm sự phụ thuộc giữa các thành phần trong project. Ở đây chỉ tìm ra các điểm tương đồng và khác biệt trong khi áp dụng DDD và client architecture vào project

Sự phụ thuộc các thành phần trong CA:

Giữa các layer có sự phụ thuộc 1 chiều với nhau, không có ngược lại (dependency injection), domain layer là trung tâm không phục thuộc vào các layer khác. Do đó khi ứng dụng thay đổi về logic, thêm tính năng mới có thể dễ dàng update, mở rộng.

Ví dụ

Giả sử một api update thông tin voucher cho khách hàng, với mỗi voucher sẽ được giảm một số tiền nào đó. Ngoài ra, có thể cần lấy thông tin từ API bên thứ 3 như thông tin user, lịch sử mua hàng,… Project này có thể được cấu trúc như sau:

Structure

- `app/`
    - `__init__.py` (initializes the application)
    - `domain/` (contains entities, value objects, and interfaces)
        - `__init__.py`
        - `interfaces/` (directory containing all interface definitions)
            - `__init__.py`
            - `ivoucher_repository.py` (interface for VoucherRepository)
            - `ithird_party_service.py` (interface for ThirdPartyService)
        - `entities/`
            - `__init__.py`
            - `voucher.py` (contains the voucher entity class)
        - `value_objects/`
            - `__init__.py`
            - `money.py` (contains the Money value object class)
    - `application/` (contains use cases and workflows)
        - `__init__.py`
        - `voucher_service.py` (contains the VoucherService class)
    - `infrastructure/` (contains technical details like database and web server)
        - `__init__.py`
        - `repositories/`
            - `__init__.py`
            - `voucher_repository.py` (implementation of VoucherRepository interface)
        - `services/`
            - `__init__.py`
            - `third_party_service.py` (implementation of ThirdPartyService interface)
    - `main.py` (entry point for the FastAPI application)

main.py

from fastapi import FastAPI

from app.application.voucher_service import VoucherService
from app.domain.entity.voucher import Voucher
from app.domain.model.money import Money
from app.infrastructure.repository.voucher_repository import VoucherRepository
from app.infrastructure.service.third_party_service import ThirdPartyService

import uvicorn

app = FastAPI()

# Dependency injection
voucher_repo = VoucherRepository()
third_party_service = ThirdPartyService(base_url="localhost")
voucher_service = VoucherService(voucher_repo, third_party_service)


@app.post("/voucher")
async def create_voucher(title: str, start_date: str, end_date: str, initial_bid: Money):
    voucher = Voucher(title, start_date, end_date, initial_bid)
    await voucher_service.create_voucher(voucher)
    # save voucher to the repository
    return {"message": "Voucher created successfully!", "voucher": voucher.__dict__}


# Start application using unicorn
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora