考える場所

ココロとカラダ、思考する全部

CQRSの小さな演習(4) エンティティとファクトリ

前回、ドメインにおけるイベントとコマンドについて考えてみました。今回はコマンドをどのようにイベントに繋げていくかを見ていくことにします。

エンティティ(集約)

分かりやすいところでイベントFixedDidの発生から考えます。

f:id:fukuchiharuki:20160319105806p:plain

これらのイベントはエンティティTodoが起こすようにします。

class Todo {
  public void fix(Doing doing) {
    Fixed fixed = new Fixed(this.id, doing);
    EventBus.instance().publish(fixed);
  }
  public void doIt() {
    Did did = new Did(this.id, new DoneAt(new Now()));
    EventBus.instance().publish(did);
  }
}

呼ぶ側からしてみたら次のようになりますね。

Todo todo;
todo.doIt(); // or todo.fix(doing);

ファクトリ

次にAddedはどのように発生させようかと考えます。

f:id:fukuchiharuki:20160625114152p:plain

Addedはエンティティができた、ということなので、エンティティのメソッドにするのはおかしな気がします。そのエンティティが既にできていることになってしまうので。そこで、ここはTodoFactoryAddedを起こすようにしてみました。

class TodoFactory {
  public TodoFactory(Doing doing) { this.doing = doing; }
  public void add() {
    Added added = new Added(new Id(), doing);
    EventBus.instance().publish(Added);
  }
}

ここでTodoBuilderはドメイン上の意図を表現するのではなく、単にTodoをインスタンス化する手続きを切り出したものです。ファクトリがエンティティと同じくイベントを起こす役割をもっているで、別途ビルダーがインスタンス化の手続きを担うようにしました。ここでTodoをインスタンス化する必要はないのでやめました。

呼ぶ側ではこうです。

new TodoFactory(doing).add();

コマンドハンドラ

ところで呼ぶ側は何者なんです、を次に考えます。

f:id:fukuchiharuki:20160319112654p:plain

コマンドAdd Fix Doに対して、それぞれコマンドハンドラAddProcessor FixProcessor DoProcessorを設けます。

class AddProcessor {
  public void receive(Add command) {
    new TodoFactory(command.getDoing()).add();
  }
}
class FixProcessor {
  public void receive(Fix command) {
    todo.fix(command.getDoing());
  }
}
class DoProcessor {
  public void receive(Do command) {
    todo.doIt();
  }
}

これらコマンドハンドラが、〜層と呼ぶところのサービスに相当するのだと思います。

次回は、

今回いつの間にか存在しているエンティティがどこからやってくるのかということについて、リポジトリを考えてみたいと思います。

blog.fukuchiharuki.me

最初

blog.fukuchiharuki.me