ComponentとDomainをつなぐ。
- 新規にEntityを作成し、Repositoryに保存
- Repositoryから既存のEntityを取りだす
- Entityに変更を加えて、Repository保存
その際に必要な情報をInfraのAPIを使い外部と通信を行い取得したりする。
1UseCase1ファイル。
UseCaseは入れ子|拡張とすることもできるが、できるかぎりUseCaseの再利用は避ける。 ドメインが正しく振る舞いを持っていれば、UseCaseの再利用をするケースは少なくなる。
例) OuterUseCase#executeがInnerUseCaseを呼びだす。
InnerUseCase#execute()
の返り値(resolvedされた値)を使うOuterUseCaseは許容しない。
execute関数では、非同期ならPromiseを返す、そうでないなら何も返さない。
その返した値を利用することはできるだけ避ける。(then/catchの成功/失敗だけを見る)
動詞 + 名詞(対象) + UseCase
命名例は次のとおり。
ChangeTitleUseCase
EnterFullScreenUseCase
UseCaseはDomainの流れを意識した命名にする。 UIを意識したClickButtonUseCaseといった名前は付けない。
UseCaseはアクターから見た能動的な名前にし、受動的な名前を避ける。
基本的にはdomain/ またはstore/ と同じディレクトリ名で揃える。
- store
- viewer/
- domain
- viewer/
- use-case
- viewer/
変更があったentityをRepository#saveすることで、RepositoryのChangeイベントが走る。 Store内で、Repository#onChangeにハンドラを渡すことで、Changeのイベントとのつなぎ込みを行う。
execute内で、this.dispatchを叩くことで、UseCaseからイベントを発することができる。 Store#onDispatchにハンドラを渡すことで、UseCaseからのイベントとのつなぎ込みを行う。 dispatch関数の引数には次の様な形式のオブジェクトを渡す。
{
type: 'HogeFugaUseCase',
hoge: fuga
}
payloadオブジェクトの type
に利用する定数はUseCaseクラス内にstaticで定義する。
export class EnterTagEditingUseCase extends UseCase {
static EVENT = {
ENTER: Symbol('EnterTagEditing')
};
execute() {
this.dispatch({
type: Symbol('EnterTagEditingUseCase.EVENT.ENTER')
});
}
}
- 対象ディレクトリがない場合は作成
- 対象ディレクトリ下に
HogeFugaUseCase.js
を配置 - constructorで依存するRepositoryなどを受け取る
- executeで実行に必要な値を受け取る
- execute内部で通信が発生する場合は、そのPromiseを返すようにする
- entityの新規作成や、変更を行った場合はRepository#saveをする
- Stateへ直接イベントを送りたい場合はthis.dispatchを利用する
- 依存を解決するためのHogeFugaFactoryを作成