りゅうじの学習blog

学習したことをアウトプットしていきます。

5/31 ドメイン駆動設計Chapter9 9-2 2

続 9-2 採番処理をファクトリに実装した例の確認

書籍では、採番処理をデータベースの操作をして行っていました。こちらをUserエンティティに記述するのは、高レベルな概念のUserに低レベルな概念のデータベースの操作を記述する悪い例です。そして、テスト用ではデータベースに接続することなく、気軽にインスタンスを生成する際に適当なIDを振り、またデータベースに接続して採番を行えるように、簡単に切り替えが行えるようにもしたい。

こういった時に、ファクトリが役に立ちます。

テスト用、データベースに接続用と切り替えを可能にするために、インターフェースも用意します。

今回、ライブラリを使ってuuidを生成して採番する方法を例にしました。

書籍のようにデータベースには接続しませんが、やっていることは同じです。

Userエンティティ

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

ファクトリのインターフェース

interface IUserFactory {
  create(name: UserName): User;
}
  • ファクトリに定義されているUserNameを引数に取り、Userのインスタンスを返却するメソッドはUserを新規作成する際にコンストラクタの代わりとして利用されます

ファクトリの実装クラス

export class UserFactory implements IUserFactory {
  create(name: UserName): User {
    const id = new UserId(uuidv4());
    return new User(id, name);
  }

ファクトリを利用するようになると、UserApplicationServiceのユーザ登録処理ではUserのインスタンスの生成をファクトリ経由で行うようになります。

class UserApplicationService {
  constructor(private userFactory: IUserFactory, private userRepository: UserRepository) {}

  async createUser(name: string) {
    const userName = new UserName(name);
    const user = this.userFactory.create(userName);
    
    await this.userRepository.save(user);
    
    return user;
  }
}

参考

ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本