TypeScript上級

上級 TypeScriptで学ぶドメイン駆動設計|解説編

導入

ドメイン駆動設計(DDD)は、複雑なビジネスロジックを明確にモデル化するための強力なアプローチです。特に、TypeScriptを使用することで、型安全性を活かしつつ、ビジネスドメインの理解を深めることができます。本記事では、実際の業務におけるシチュエーションを通じて、ドメイン駆動設計の実践的な側面を探ります。

教科書レベルの解説(ドメイン駆動設計)

重要な概念の整理

ドメイン駆動設計の核心は、ビジネスドメインに対する深い理解と、それに基づくモデルの構築です。ドメインモデルは、ビジネスのルールやプロセスを反映したオブジェクトの集合です。このモデルを中心に、システム全体が設計されます。エンティティ、値オブジェクト、集約、リポジトリなどの概念が、ドメインモデルを構成する要素として重要です。

コード例(TypeScript)


class User {
    constructor(public id: string, public name: string) {}

    changeName(newName: string) {
        this.name = newName;
    }
}

class UserRepository {
    private users: Map = new Map();

    add(user: User) {
        this.users.set(user.id, user);
    }

    findById(id: string): User | undefined {
        return this.users.get(id);
    }
}

const userRepo = new UserRepository();
const user = new User("1", "Alice");
userRepo.add(user);
user.changeName("Bob");

コードの行ごとの解説

  1. class User { ... }:ユーザーモデルを定義します。ユーザーのIDと名前を属性として持ち、名前を変更するメソッドを提供します。
  2. class UserRepository { ... }:ユーザーのリポジトリを定義します。ユーザーを保存するためのMapを使用しています。
  3. add(user: User) { ... }:ユーザーをリポジトリに追加するメソッドです。
  4. findById(id: string): User | undefined { ... }:IDを使ってユーザーを検索するメソッドです。
  5. const userRepo = new UserRepository();:リポジトリのインスタンスを生成します。
  6. const user = new User("1", "Alice");:新しいユーザーを作成します。
  7. userRepo.add(user);:作成したユーザーをリポジトリに追加します。
  8. user.changeName("Bob");:ユーザーの名前を変更します。

解説編

この例では、ユーザーを管理するためのシンプルなドメインモデルを構築しました。重要な点は、エンティティ(User)が自らの状態を変更できるメソッドを持つことで、ビジネスロジックがモデル内に閉じ込められていることです。これにより、外部からの不正な状態変更を防ぎ、オブジェクト指向の原則に基づいた堅牢な設計が実現されます。

落とし穴として、リポジトリがビジネスロジックを持つことは避けるべきです。リポジトリはデータの永続化に専念し、ビジネスロジックはエンティティやサービスに分散させることが望ましいです。この設計思想を適用することで、システムの拡張性や保守性が向上します。

まとめ

  • ドメイン駆動設計はビジネスロジックを中心に据えたアプローチである。
  • TypeScriptを用いることで、型安全性を活かしたモデル設計が可能となる。
  • リポジトリはデータアクセスの役割に専念し、ビジネスロジックはエンティティやサービスに分散させるべきである。