Interactive

設計

設計は、変更の影響と業務上の制約をどこに閉じ込めるかを決めることから始めます。アーキテクチャでは、処理の複雑さに応じた境界と依存関係の考え方を共有します。

個々の設計手法は、名前を付けるだけで品質を上げるものではありません。弊社では、言語やフレームワークの既定だけでは選ばれにくく、明示的な判断がなければ採用されにくい手法を、採用条件とセットで共有します。

最初からすべてを組み合わせず、現在ある問題を最も小さく解決できる手法を選びます。パターン名より、守りたい制約と導入後の負担を説明できることを重視します。

概要

型と状態に関する手法は、誤った値や操作を実装の早い段階で検出するために使います。ブランド型と幽霊型は、同じプリミティブ型の取り違えやAPIの呼び出し順を型で制限します。ステートマシンは、業務で許可される状態と遷移を明示します。Reducerは、複数のイベントによる状態更新を一つの純粋関数へ集約します。

ドメインの値そのものに不変条件や振る舞いがある場合は、Value Objectとして表現します。外部システムとの境界では、AdapterとGatewayで外部の型やエラーを内部へ持ち込まないようにし、Dependency Injectionで依存の生成と利用を分けます。複雑なドメインモデルを永続化の都合から分離する必要がある場合は、Repositoryを使います。

オブジェクトの生成に検証や実装の選択が伴う場合は、FactoryとFactory Methodへ判断を集約します。任意項目が多く、一度に生成すると読みづらい場合はBuilderで段階的に組み立てます。利用側へ複数の操作を提供するときは、ドメインの語彙で一連の操作を読めるFluent APIと、複数の下位機能を単純な入口へまとめるFacadeを目的に応じて使い分けます。

共通の判断基準

  • 問題が単純な関数、オブジェクト、Union型で解けるなら、先にそちらを使う
  • 導入理由を「将来使うかもしれない」ではなく、現在の利用箇所で説明する
  • 型による保証と、実行時の検証・認可・トランザクションを混同しない
  • 抽象化の内側に、外部ライブラリの型、エラー、ライフサイクルを閉じ込める
  • パターンを外しても読みやすいほど単純になったら、パターンを外す

参考資料