Functional and Reactive Domain Modeling 各章まとめ


* [Functional and Reactive Domain Modeling](https://www.manning.com/books/functional-and-reactive-domain-modeling)とは、ドメイン駆動設計(DDD)の関数型プログラミング(FP)とリアクティブプログラミング(RP)によるアプローチを書いた本


## 1. 関数型ドメインモデリング：イントロダクション

* 変更可能なステートを避ける - 変更可能なステートは管理が難しく、非決定性につながる

* 参照透過性 - FPは、参照透過なモデルコンポーネントを設計する能力を提供する。モデルの振る舞いが純粋関数で構築されていることで合成性を得られ、小さな関数から大きな関数を作ることができる

* 自律的成長 - 関数型の設計と思考で、モデルは自律的に成長する。純粋性故にモデルは数学的に扱うことができ、推論ができる

* コアドメインに集中する - DDDの原則を使用してモデルを構築すると、リポジトリやファクトリといったパターンに基づいて編成されたエンティティや値オブジェクトやサービスを持ち、そして、それらを関数型にできる。DDDコードの各レイヤーで不変性も努める

* 関数型はリアクティブを容易にする - 純粋関数は、変更可能なステートの管理を全く心配することなく並列処理に割り当てられるので、リアクティブモデリングの理想的な候補となる

* 障害のための設計 - 処理が失敗しないことを前提にしない。例外ハンドラとビジネスロジックコードを結合することなく、別の問題として管理しよう

* イベントベースモデリングが関数型モデルを補完する - イベントベースプログラミングはモデルのHowからWhatを描き出す。イベントはWhatを指定するメッセージで、イベントハンドラではHowを記述する。


## 2. 関数型ドメインモデリングのためのScala
どんな言語でもドメインモデリングはできるが、Scalaはより高いレベルの抽象度でプログラムができる言語の1つだ。

* 強力な型システム - ドメインロジックの一部をコード化するために効果的に使用できる強力な型システムがあり、ボイラープレートや不要なテストコードを削減できる

* ファーストクラスのサポート - 標準ライブラリで高階関数とコンビネータをサポートしている。ファーストクラスな抽象化として関数を使用することで、参照透過的であり、それゆえに合成性のある、ドメインの振る舞いを実装できる

* 代数的データ型(ADT)とパターンマッチングのサポート - ADTとパターンマッチングの組み合わせは、簡潔にドメインロジックを表現する強力な手段を提供する

* ファーストクラスなモジュール - トレイトとオブジェクトは、合成可能なモジュール定義に役立ち、小さなコンポーネントから大きなコンポーネントへ発展させるのに役立つ


## 3. 関数型ドメインモデルの設計
ドメインモデリングの基本パターンと、代数技術でのドメインモデルのAPI設計へのアプローチ方法
代数的API設計は基本概念の1つである

* 代数で考える - オブジェクト指向(OO)でAPIを設計する方法とは異なる。

* 型駆動合成 - まず個々のAPIの代数を識別してから、型を揃えてコンピューテーションを使って大きな振る舞いを合成する

* 関心の分離 - 代数からインタプリタを分離する。

* 一貫性の単位としての集約 - 集約の一貫性境界を強制するために、モジュールに代数法則を使用する

* ドメインオブジェクトパターンの関数型実装 - ADTを使用して集約を設計、Lensを使用して更新、リポジトリを設計、Readerモナドなどを使用したドメインサービスにリポジトリを注入、ファクトリを実装するためのスマートコンストラクタ

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch3)


## 4. ドメインモデリングのための関数型パターン

* 関数型デザインパターンとは - OOと異なり、FPでは抽象化の代数となる。

* ユビキタスモノイド - モノイドはモデルを汎用的にし、ドメインの操作越しの抽象化に役立ちます

* 効果的なプログラミングのためのパターン - FPで最も使用される3つのパターンは、Functor、Applicative、Monadである。

* パターンの良さ - 関数型パターンの適用がドメインモデルを合成性を有し、パラメトリックで、再利用可能にする。

* フィールドから実装#1 - 型と関数の力を使ってAPIを進化させる。ドメインの振る舞いのワークフローを設計するために、Kleisliで効果的な関数合成を使用する

* フィールドから実装#2 - ドメイン定数を静的に強制するためにファントム型を使用する。

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch4)


## 5. ドメインモデルのモジュール化
モジュラー・ソフトウェアの作成方法を学ばない限り、モデルはモノリシックなコードになる。そして、それは長期的にリファクタリング、拡張、保守を難しくする。Scalaでモデルをモジュールに分解する

* モジュール化とは - モデルを、関連する振る舞いを意味的にグループ化する小さなモジュールに分解することである。モジュールとは、代数と実装で、代数を公開して実装を保護する

* モジュールの仕組み - ドメインからモジュールフラグメントを取り出し、それをモジュールに分解する。代数を設計し、ドメインの振る舞いを見て、代数を構成する。また、実装を代数から切り離す

* 合成性 - モジュール代数内で定義するドメインの振る舞いは、代数を使用する合成コードを記述できるように構成する必要がある

* モジュールの物理的構成 - ドメイン要素はmodelパッケージに、サービスモジュール代数はserviceパッケージに、インタプリタはinterpreterパッケージに

* 型クラスパターン - ポリモーフィズムを実装できる。事後に既存クラスに振る舞いを追加できる

* 境界づけられたコンテキスト - モジュール化のより高い粒度を提供する

* Freeモナド - スキップしていい上級者向けのパターン

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch5)


## 6. リアクティブ
ドメインモデルをリアクティブにする方法

* リアクティブドメインモデルとは - 障害、負荷、非同期メッセージングに即時応答性を持つモデル

* FutureとPromise - FutureとPromiseを使用してリアクティブノンブロッキングAPIを設計する

* 非同期メッセージング - システム間通信に最もよく使われる技術

* Streamモデル - Streamはドメインの振る舞いのパイプラインをモデリングするための型付きの抽象化を提供する

* Actorモデル - ドメインモデルをスケーラブルにできる

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch6)


## 7. Reactive Streamsでモデリング

* ドメインモデリングにReactive Streamsを使用する - ストリームベースのモデルを使用する根拠と、ストリームベースのバックボーンを使用してリアクティブアーキテクチャの原則を実装する

* 非同期境界のハンドリング - Reactive Streamsは非同期境界をハンドリングするための便利な実装で、それによってコンテキストは空間と時間に分離される

* ネイティブのActorより優れている - Reactive Streamsの実装であるAkka Streamsは、アーキテクチャの正当性を推論できる静的型付けプログラミングモデルを提供する

* 耐障害性の管理 - 冗長性のためのクラスタリング、集中管理された障害管理の監視、インメモリデータ損失を防ぐための永続性

* Back Pressureのハンドリング - Akka Streamsは、ConsumerとProducer間のBack Pressureを制御し、それによってConsumerがFast Producerによって抑制されるのを防ぐ

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch7)


## 8. リアクティブな永続性とEvent Sourcing
ドメインモデル要素の格納にはリレーショナルデータベースだと当然のように考える時代は終わっている
Event SourcingとCQRSは、データのインプレース更新という概念を避け、代わりにドメインモデルを不変のイベントストリームとして保存する

* CRUDは永続化の唯一無二のモデルではない - ドメインイベントを格納する技術としてEvent Sourcing。Event Sourcingはモデルの監査・追跡をより容易にする。

* イベントソースドメインモデルを関数型で実装する - イベントソースモデルの実装は関数型プログラミングの原則とよく合う

* ORMではなくFRM - CRUDモデルを永続化に使用する場合、Slickなど関数型リレーショナルマッピングフレームワークを使用する

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch8)


## 9. ドメインモデルのテスト

* テスタビリティはモジュラリティと密接に関連している。ドメイン成果物間の関心の分離を保証する必要がある。

* xUnitテストの欠点と、代替手段としてのプロパティベーステストの使い方

* プロパティベーステストは、ジェネレータを通してデータを生成でき、データはきめ細かく制御できる。ドメインモデルの代数プロパティを定義・検証するためにジェネレータを使用できる

[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/main/scala/frdomain/ch9)
[サンプルコード](https://github.com/debasishg/frdomain/tree/master/src/test/scala/frdomain/ch9)


## 10. まとめ - 基本思想と基本原則

* 反復が大事。ドメインモデルを実装するたびに読み返そう
* 本書の多くのセクションで言及したように、解決策は、すっきりしていて、きれいで、ドメインフレンドリーで、基礎実装のインシデントの複雑さを全く持っていないインターフェイスをユーザーに提示することである
* Haskellは副作用をはるかに厳密に分離できる。Haskellのような言語でドメインモデリングすることが将来のトレンドになることを期待
* 関数型プログラミングの数学的土台が、ドメインモデルをモジュール化するための最強の基盤を提供する


## 読書会やってます

今回紹介した "Functional and Reactive Domain Modeling" (Debasish Ghosh 著) の読書会に参加しています。興味のある方はぜひご一緒しましょう！

[Functional and Reactive Domain Modeling 読書会 - connpass](https://functional-and-reactive-domain-modeling.connpass.com/)