首頁 > web前端 > js教程 > 用於領域驅動設計 (DDD) 的 TypeScript

用於領域驅動設計 (DDD) 的 TypeScript

Patricia Arquette
發布: 2024-12-25 17:18:14
原創
506 人瀏覽過

領域驅動設計(DDD)是一種透過專注於核心業務領域及其相關邏輯來處理複雜軟體系統的強大方法。 TypeScript 具有強大的類型和現代功能,是有效實現 DDD 概念的優秀工具。本文探討了 TypeScript 和 DDD 之間的協同作用,提供了實用的見解、策略和範例來彌合設計和程式碼之間的差距。

了解領域驅動設計

核心概念

1。無所不在的語言
開發人員和領域專家之間使用共享語言進行協作,以減少溝通不良。

2。有界上下文
領域的不同部分清晰分離,確保特定上下文中的自主性和清晰度。

3。實體和值物件

  • 實體:具有唯一識別的物件。
  • 值物件:由其屬性定義的不可變物件。

4。聚合
領域物件的集群被視為資料更改的單一單元。

5。儲存庫
抽象持久化邏輯,提供對聚合的存取。

6。領域事件
當域內發生重大操作時發出訊號。

7。申請服務
封裝業務工作流程和編排邏輯。

為什麼 TypeScript 適合 DDD

1。靜態類型: 強型別檢查有助於明確建模域邏輯。
2.介面: 在元件之間執行契約。
3.類別: 自然地表示實體、值物件和聚合。
4.類型防護: 確保運作時的型別安全。
5.實用程式類型: 為動態域啟用強大的型別轉換。

實際實施

1。建模實體
實體具有獨特的身份並封裝行為。

class Product {
  constructor(
    private readonly id: string,
    private name: string,
    private price: number
  ) {}

  changePrice(newPrice: number): void {
    if (newPrice <= 0) {
      throw new Error("Price must be greater than zero.");
    }
    this.price = newPrice;
  }

  getDetails() {
    return { id: this.id, name: this.name, price: this.price };
  }
}
登入後複製
登入後複製



2.建立值物件
值物件是不可變的並按值進行比較。

class Money {
  constructor(private readonly amount: number, private readonly currency: string) {
    if (amount < 0) {
      throw new Error("Amount cannot be negative.");
    }
  }

  add(other: Money): Money {
    if (this.currency !== other.currency) {
      throw new Error("Currency mismatch.");
    }
    return new Money(this.amount + other.amount, this.currency);
  }
}
登入後複製
登入後複製



3.定義聚合
聚合確保邊界內的資料一致性。

class Order {
  private items: OrderItem[] = [];

  constructor(private readonly id: string) {}

  addItem(product: Product, quantity: number): void {
    const orderItem = new OrderItem(product, quantity);
    this.items.push(orderItem);
  }

  calculateTotal(): number {
    return this.items.reduce((total, item) => total + item.getTotalPrice(), 0);
  }
}

class OrderItem {
  constructor(private product: Product, private quantity: number) {}

  getTotalPrice(): number {
    return this.product.getDetails().price * this.quantity;
  }
}
登入後複製
登入後複製



4.實作儲存庫
儲存庫抽象資料存取。

interface ProductRepository {
  findById(id: string): Product | null;
  save(product: Product): void;
}

class InMemoryProductRepository implements ProductRepository {
  private products: Map<string, Product> = new Map();

  findById(id: string): Product | null {
    return this.products.get(id) || null;
  }

  save(product: Product): void {
    this.products.set(product.getDetails().id, product);
  }
}
登入後複製



5.使用領域事件
領域事件通知系統狀態變化。

class DomainEvent {
  constructor(public readonly name: string, public readonly occurredOn: Date) {}
}

class OrderPlaced extends DomainEvent {
  constructor(public readonly orderId: string) {
    super("OrderPlaced", new Date());
  }
}

// Event Handler Example
function onOrderPlaced(event: OrderPlaced): void {
  console.log(`Order with ID ${event.orderId} was placed.`);
}
登入後複製



6.申請服務
應用程式服務協調工作流程並執行用例。

class OrderService {
  constructor(private orderRepo: OrderRepository) {}

  placeOrder(order: Order): void {
    this.orderRepo.save(order);
    const event = new OrderPlaced(order.id);
    publishEvent(event); // Simulated event publishing
  }
}
登入後複製

7. 使用有界上下文

利用 TypeScript 的模組化功能來隔離有界上下文。

  • 為每個上下文使用單獨的目錄。
  • 明確定義跨上下文通訊的介面。

結構範例:

class Product {
  constructor(
    private readonly id: string,
    private name: string,
    private price: number
  ) {}

  changePrice(newPrice: number): void {
    if (newPrice <= 0) {
      throw new Error("Price must be greater than zero.");
    }
    this.price = newPrice;
  }

  getDetails() {
    return { id: this.id, name: this.name, price: this.price };
  }
}
登入後複製
登入後複製

進階功能

靈活建模的條件類型

class Money {
  constructor(private readonly amount: number, private readonly currency: string) {
    if (amount < 0) {
      throw new Error("Amount cannot be negative.");
    }
  }

  add(other: Money): Money {
    if (this.currency !== other.currency) {
      throw new Error("Currency mismatch.");
    }
    return new Money(this.amount + other.amount, this.currency);
  }
}
登入後複製
登入後複製

用於驗證的範本文字類型

class Order {
  private items: OrderItem[] = [];

  constructor(private readonly id: string) {}

  addItem(product: Product, quantity: number): void {
    const orderItem = new OrderItem(product, quantity);
    this.items.push(orderItem);
  }

  calculateTotal(): number {
    return this.items.reduce((total, item) => total + item.getTotalPrice(), 0);
  }
}

class OrderItem {
  constructor(private product: Product, private quantity: number) {}

  getTotalPrice(): number {
    return this.product.getDetails().price * this.quantity;
  }
}
登入後複製
登入後複製

我的個人網站:https://shafayet.zya.me


嗯,這表明你在 Git-toilet 中有多活躍......

TypeScript for Domain-Driven Design (DDD)


封面圖片是

使用OgImagemaker製作的 @eddyvinck。謝謝男人給我們這個工具? ? ? ...

以上是用於領域驅動設計 (DDD) 的 TypeScript的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板