クリーンアーキテクチャとは
まず以下の記事を推す。
持続可能な開発を目指す ~ ドメイン・ユースケース駆動(クリーンアーキテクチャ) + 単方向に制限した処理 + FRP
私なりの要点は次の通り
* 内側から、DomainModel/Usecase/Interface Adapter/External Adapter
* Interface Adapterが内と外を変換する単一方向のパイプのようなもの
* 外から内への入力がController、内から外への出力がPresenter、入出力を分離する必要がない場合はGateway
* Usecaseに業務手順を書き下す。業務手順の明示的なテストができるって凄い
* Usecase中では、Contolerからの入力で、DB−Gatewayからデータを得て、Presenterに出力し反映など。パイプを繋ぎ直しているようなイメージ
* 出力パイプであるPresenterは他のUsecaseの入力になったりはしない(ようにすべき)
* 出力先が別れる時はUsecase中で分ける。パイプはステートレスだから完全に個別にテストできる。素晴らしい
実装で理解したい場合
クリーンアーキテクチャの右下の図
- インタフェースがうんたらは置いておいて、いかに単一方向のパイプであるかイメージできた
- 生成する順番は、outportつまり外側から、interactor=Usecase、その次にcontroller。以下が秀逸
static void Main(string[] args)
{
    var outputPort = CreateOutputPort();
    var interactor = CreateInputPort(outputPort);
    var controller = new Controller(interactor);
    controller.Execute(new[] {"source", "data", "foo", "bar"});
}
- JavaScriptでは、最近、DOMContentLoadedをよく目にします。
原典
クリーンアーキテクチャ(The Clean Architecture翻訳)
JavaScriptで実践
勤務実績一覧
- 人を選んだら過去勤務実績を年度/毎月(概要あり)のタブ区切りで表示する
- 毎月、何時間働いたか、その内訳は何か
 
- 選択ユースケース
- 選択した所属部門に属する人だけ絞込可能
- 選択可能な従業員の勤務形態も同時変更
 
- さらに選択した勤務形態(社員/パート)でも絞込可能
- この場合は所属部門は絞り込まれない
 
- 同様に、勤務した個別月から絞込可能
 
- 選択した所属部門に属する人だけ絞込可能
UIイメージ
早速困ったこと
- Usecaseの粒度
- ひとまず、class Usecaseで一つ
- FilterUsecase#changeDepartment(i, department)
- FilterUsecase#changeLabortype(i, labortype)
- FilterUsecase#changeMember(i, member)
 
- UIセレクトボックス中の選択状態は?どこに?
- filterUC.cond = {department: ?, labortype: ?, member: ?}
- ひとまずUsecaseに?持たせる(いいの?)
 
class FilterUsecase {
  changeDepartment(i, department){//まずは部門で絞込
    this.cond = {department : (i < 1) ? null : department}
    const 勤務実績表 = this.repository.q("勤務実績", this.cond);
    this.oport["memberfilter"].update(勤務実績表, this)
  }
  // this.outport["memberfilter"]の実態は、Presenterとする
}
class Presenter
  constructor(id){
    this.node = document.getElementById(id)
  }
  update(table, usecase){
    //勤務実績repositotyから得られたtableを変換してUIに反映する
    //1. Table -> Arrayへ変換 -> domへの中間表現 vdomに変換
    const arr  = this.selectMember(table)
    const vdom = this.toSelectBox(arr)
    //2. vdomの内容を、DOMに反映
    this.node.appendChild(toDom(vdom).addEventLister("change", (evt)=>{
     const i = this.selectedIndex;
     const member = this.options[i].text
     usecase.changeMember(i, member)
    }))
  }
- Table->Arrayへの変換はPresenterの役割?Usecaseの役割?
- Array->vdomへの変換はPresenterの役割?Usecaseの役割?
- vdom->DOMへの反映時に
- 部門セレクトボックスの選択で、氏名セレクトボックスが更新される
- さらに、氏名セレクトボックスはonchangeイベントハンドラを持つ必要がある
- onchangeイベントによって最終的に特定一名を指定する
- 従って、changeDepartment()がFilterUsecaseにある以上、usecaseレシーバが引数で与えられる必要がある
- 部門を毎回選択する度に、appendChildするNodeListを消して付け加えるのは冗長では?
- optionタグ分だけを入れ替えれば良いはず
 
- ...
Usecase編へ続く
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(前編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(Usecase編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(Presenter編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(initializer編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(Repository編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(DataStore編)
- JavaScriptでクリーンアーキテクチャはどうすればいいのか(DomainModel編)
