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

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

Dec 10, 2024 am 01:53 AM

在當今快節奏的軟體開發環境中,建立易於維護、適應和擴展的應用程式至關重要。六角形架構(也稱為連接埠和適配器)和領域驅動設計(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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到? 如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到? Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

在Linux終端中使用python --version命令時如何解決權限問題? 在Linux終端中使用python --version命令時如何解決權限問題? Apr 02, 2025 am 06:36 AM

Linux終端中使用python...

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎? 如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎? Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何繞過Investing.com的反爬蟲機制獲取新聞數據? 如何繞過Investing.com的反爬蟲機制獲取新聞數據? Apr 02, 2025 am 07:03 AM

攻克Investing.com的反爬蟲策略許多人嘗試爬取Investing.com(https://cn.investing.com/news/latest-news)的新聞數據時,常常�...

Python 3.6加載pickle文件報錯ModuleNotFoundError: No module named '__builtin__'怎麼辦? Python 3.6加載pickle文件報錯ModuleNotFoundError: No module named '__builtin__'怎麼辦? Apr 02, 2025 am 06:27 AM

Python3.6環境下加載pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

使用Scapy爬蟲時,管道文件無法寫入的原因是什麼? 使用Scapy爬蟲時,管道文件無法寫入的原因是什麼? Apr 02, 2025 am 06:45 AM

使用Scapy爬蟲時管道文件無法寫入的原因探討在學習和使用Scapy爬蟲進行數據持久化存儲時,可能會遇到管道文�...

See all articles