導入
ドメイン駆動設計(DDD)は、複雑なビジネスロジックを扱う際に非常に効果的なアプローチです。特に、実務においては、ドメインの理解がシステム全体の設計に大きな影響を与えます。今回は、TypeScriptを用いて、現場でよく遭遇する「注文管理システム」を題材に、ドメイン駆動設計の実践的な適用方法を考えていきます。
教科書レベルの解説(ドメイン駆動設計)
重要な概念の整理
ドメイン駆動設計では、ドメインモデルを中心にシステムを構築します。具体的には、エンティティ、値オブジェクト、集約、リポジトリなどの概念を用いて、ビジネスルールを明確にし、システム全体の整合性を保つことが求められます。特に注文管理システムでは、注文の状態遷移や、注文に関連するビジネスロジックが重要なポイントとなります。
コード例(TypeScript)
class Order {
private items: OrderItem[] = [];
private status: OrderStatus;
constructor(private id: string) {
this.status = OrderStatus.CREATED;
}
public addItem(item: OrderItem): void {
if (this.status !== OrderStatus.CREATED) {
throw new Error("Cannot add items to an order that is not in the CREATED status.");
}
this.items.push(item);
}
public checkout(): void {
if (this.items.length === 0) {
throw new Error("Cannot checkout an empty order.");
}
this.status = OrderStatus.COMPLETED;
}
public getStatus(): OrderStatus {
return this.status;
}
}
enum OrderStatus {
CREATED,
COMPLETED,
}
class OrderItem {
constructor(public productId: string, public quantity: number) {}
}
コードの行ごとの解説
- class Order { – 注文を表すクラスの定義。
- private items: OrderItem[] = []; – 注文に含まれるアイテムを保持する配列。
- private status: OrderStatus; – 注文の状態を管理するプロパティ。
- constructor(private id: string) { – 注文のIDを初期化するコンストラクタ。
- this.status = OrderStatus.CREATED; – 注文作成時の初期状態を設定。
- public addItem(item: OrderItem): void { – 注文にアイテムを追加するメソッド。
- if (this.status !== OrderStatus.CREATED) { – 注文の状態をチェックし、アイテム追加の可否を判断。
- public checkout(): void { – 注文を完了するメソッド。
- if (this.items.length === 0) { – 注文が空でないかを確認。
- public getStatus(): OrderStatus { – 現在の注文状態を取得するメソッド。
練習問題編
以下の練習問題に取り組んでみてください。
-
問題1: 注文にアイテムを追加する際、アイテムの数量が0以下の場合はどうなるか、エラーハンドリングを追加してください。
public addItem(item: OrderItem): void { if (item.quantity <= 0) { throw new Error("Item quantity must be greater than zero."); } // 既存のロジック } -
問題2: 注文の状態を「キャンセル」に変更するメソッドを追加してください。
public cancel(): void { if (this.status === OrderStatus.COMPLETED) { throw new Error("Cannot cancel a completed order."); } this.status = OrderStatus.CANCELLED; } -
問題3: 注文のアイテムを取得するメソッドを実装してください。
public getItems(): OrderItem[] { return this.items; }
まとめ
- ドメイン駆動設計は、ビジネスロジックの明確化に寄与する。
- エンティティと値オブジェクトの役割を理解し、適切に利用することが重要。
- 実際の業務においては、エラーハンドリングや状態管理が鍵となる。