首頁 >後端開發 >Python教學 >使用六邊形架構和領域驅動設計來建立可維護的Python應用程式

使用六邊形架構和領域驅動設計來建立可維護的Python應用程式

Patricia Arquette
Patricia Arquette原創
2024-12-10 01:53:08335瀏覽

在當今快節奏的軟體開發環境中,建立易於維護、適應和擴展的應用程式至關重要。六角形架構(也稱為連接埠和適配器)和領域驅動設計(DDD)是應對這些挑戰的有效組合。六邊形架構促進了關注點的清晰分離,使得在不破壞核心邏輯的情況下更容易替換、測試或增強系統的各個部分。同時,DDD 專注於使您的程式碼與現實世界的業務概念保持一致,確保您的系統既直觀又具有彈性。這些方法共同使開發人員能夠建立強大、有彈性的系統,並且旨在無縫適應不斷變化的需求和未來的成長。

1. 六角形架構簡介

六邊形架構,也稱為連接埠和適配器模式,由Alistair Cockburn引入,以解決傳統分層架構的剛性和複雜性。其主要目標是使應用程式的核心邏輯(域)獨立於外部系統,從而更容易測試、維護和適應性。

六邊形架構的核心將應用程式分為三個主要層:

  • 核心(業務邏輯/域):系統的核心,業務規則和域邏輯所在。該層是獨立的,不依賴外部函式庫或框架。
    範例:計算貸款利息或依照業務規則驗證使用者的操作。

  • 連接埠(介面):核心與外界互動方式的抽象定義(例如介面或協定)。連接埠代表用例或特定於應用程式的 API。他們定義了需要做什麼,但沒有指定如何
    範例: 儲存庫連接埠定義與資料來源互動的方法,例如:

    • get(id: ID): 實體:透過唯一識別碼檢索實體。
    • insert(entity: Entity): void: 新增實體。
    • update(entity: Entity): void:更新現有實體。
src/ports/repository.py
from abc import ABC, abstractmethod
from typing import List
from src.entities import Entity

class Repository(ABC):
    @abstractmethod
    def get(self, id: str) -> Entity:
        pass

    @abstractmethod
    def insert(self, entity: Entity) -> None:
        pass

    @abstractmethod
    def update(self, entity: Entity) -> None:
        pass
  • 適配器(實作): 連接埠的具體實作。它們處理與資料庫、API 或 UI 等外部系統的實際互動。 範例: PostgresRepository Adapter 使用 SQLAlchemy 實作 PostgreSQL 的儲存庫連接埠。
# src/adapters/postgres_repository.py
from sqlalchemy import create_engine, Column, String
from sqlalchemy.orm import declarative_base, sessionmaker
from src.entities import Entity
from src.ports.repository import Repository

Base = declarative_base()

# Define the database table for Entity
class EntityModel(Base):
    __tablename__ = "entities"
    id = Column(String, primary_key=True)
    name = Column(String, nullable=False)
    description = Column(String)

class PostgresRepository(Repository):
    def __init__(self, db_url: str):
        """
        Initialize the repository with the PostgreSQL connection URL.
        Example db_url: "postgresql+psycopg2://username:password@host:port/dbname"
        """
        self.engine = create_engine(db_url)
        Base.metadata.create_all(self.engine)
        self.Session = sessionmaker(bind=self.engine)

    def get(self, id: str) -> Entity:
        session = self.Session()
        try:
            entity_model = session.query(EntityModel).filter_by(id=id).first()
            if not entity_model:
                raise ValueError(f"Entity with id {id} not found")
            return Entity(id=entity_model.id, name=entity_model.name, description=entity_model.description)
        finally:
            session.close()

    def insert(self, entity: Entity) -> None:
        session = self.Session()
        try:
            entity_model = EntityModel(id=entity.id, name=entity.name, description=entity.description)
            session.add(entity_model)
            session.commit()
        finally:
            session.close()

    def update(self, entity: Entity) -> None:
        session = self.Session()
        try:
            entity_model = session.query(EntityModel).filter_by(id=entity.id).first()
            if not entity_model:
                raise ValueError(f"Entity with id {entity.id} not found")
            entity_model.name = entity.name
            entity_model.description = entity.description
            session.commit()
        finally:
            session.close()

此架構通常被形象化為六邊形,象徵著與核心互動的多種方式,每一面代表不同的適配器或連接埠。

Building Maintainable Python Applications with Hexagonal Architecture and Domain-Driven Design

2. 領域驅動設計(DDD)簡介

領域驅動設計 (DDD) 是一種軟體設計方法,強調業務目標與為實現這些目標而構建的軟體之間的緊密結合。這個方法是由 Eric Evans 在他的著作領域驅動設計:解決軟體核心的複雜性

中介紹的。

DDD 的核心是在領域專家的幫助下理解和建模領域(業務問題空間),並將這種理解轉化為軟體系統。 DDD 促進了領域的解耦,確保系統的不同部分保持獨立、清晰、易於管理。
領域驅動設計的關鍵概念:

  • 領域: 軟體涉及的知識或活動的特定領域。例如,在銀行應用程式中,網域包括帳戶、交易和客戶等概念。

  • 通用語言:由開發人員和領域專家協作開發的通用語言。這種共享詞彙確保所有利害關係人之間的清晰溝通和一致理解。

  • 實體與值物件:

    • 實體:具有獨特身分和生命週期的對象,例如客戶或訂單。
    • 值對象: 不可變的對象,由其屬性定義,而不是由唯一識別(如日期或貨幣金額)定義。
  • 聚合: 相關實體和值物件的群集被視為資料變更的單一單元。每個聚合都有一個根實體,保證整個叢集的完整性。

  • 儲存庫:檢索與儲存聚合的機制,提供資料存取的抽象層。

  • 服務:自然不適合實體或值物件但對網域至關重要的操作或流程,例如處理付款。

src/ports/repository.py
from abc import ABC, abstractmethod
from typing import List
from src.entities import Entity

class Repository(ABC):
    @abstractmethod
    def get(self, id: str) -> Entity:
        pass

    @abstractmethod
    def insert(self, entity: Entity) -> None:
        pass

    @abstractmethod
    def update(self, entity: Entity) -> None:
        pass

在本節中,我不會提供實現領域驅動設計 (DDD) 的詳細範例,因為它是一種綜合方法,主要致力於解決複雜的業務邏輯挑戰。 DDD 擅長建立和管理複雜的業務規則,但為了充分發揮其潛力並解決其他編碼問題,最好在互補的架構框架中使用它。因此,在接下來的部分中,領域驅動設計將與六邊形架構相結合,以突出其優勢,並為解決業務邏輯之外的其他編碼問題提供堅實的基礎,並附有詳細的示例。

3. 六角形架構與領域驅動設計如何相輔相成

為什麼採用六角形架構和領域驅動設計?

領域驅動設計 (DDD) 和六邊形架構透過強調清晰的邊界並使軟體與業務需求保持一致來相輔相成。 DDD 專注於對核心域進行建模並隔離業務邏輯,而六邊形架構則透過連接埠和適配器確保該邏輯獨立於外部系統。他們解決了不同但互補的問題:

  • 以六角形建築為框架:

    • 六邊形架構定義了整個系統的組織方式以及不同部分(例如網域、基礎設施、使用者介面)如何互動。
    • 它提供了域邏輯可以獨立於外部問題運作的環境,不受基礎設施細節的影響。
  • 領域驅動設計作為核心邏輯:

    • DDD 豐富了六角架構定義的核心領域,確保業務邏輯不僅被封裝,而且反映了現實世界的業務需求。
    • 它專注於如何有效地設計和實現領域層,確保其保持有意義和適應性。

它們共同實現了可擴展、可測試和靈活的系統,其中領域仍然是中心焦點,不受基礎設施或技術變化的影響。這種協同作用確保了強大的設計,可以輕鬆適應不斷變化的業務需求。
以下部分提供了一個實際範例,說明領域驅動設計 (DDD) 和六邊形架構如何協同工作來創建健全、可維護和適應性強的軟體系統。

實際例子

該專案應用六邊形架構和領域驅動設計(DDD)來創建可擴展和可維護的系統,為應用程式開發提供現代且強大的基礎。它使用 Python 構建,使用 FastAPI 作為 Web 框架,並使用 DynamoDB 作為資料庫。

專案組織如下:

src/ports/repository.py
from abc import ABC, abstractmethod
from typing import List
from src.entities import Entity

class Repository(ABC):
    @abstractmethod
    def get(self, id: str) -> Entity:
        pass

    @abstractmethod
    def insert(self, entity: Entity) -> None:
        pass

    @abstractmethod
    def update(self, entity: Entity) -> None:
        pass

您可以在我的 GitHub 儲存庫中找到原始程式碼。

4. 結論

將六邊形架構和領域驅動設計 (DDD) 合併到 Python 應用程式中,可以促進可維護、適應性強且與業務目標緊密結合的系統的開發。六邊形架構確保核心業務邏輯和外部系統之間的明確分離,提高靈活性和易於測試。 DDD 強調準確地對領域進行建模,從而產生真正反映業務流程和規則的軟體。透過整合這些方法,開發人員可以創建強大的應用程序,這些應用程式不僅可以滿足當前的要求,而且還可以根據未來的業務需求進行發展。

如果您喜歡這篇文章,請與我聯絡!

以上是使用六邊形架構和領域驅動設計來建立可維護的Python應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn