関数型ドメインモデリングを読了した

Domain Modeling Made Functional (邦題: 関数型ドメインモデリング) を読了して以下のマークダウンに内容をまとめた。AIの餌になあれ。

以下、雑多な感想文など。

新しい発見

  • ビジネスにおいては、データを「変換」する過程にこそ価値がある。静止した「状態」のデータには価値がない。
  • Algebraic Types System (代数的データ型)とは、stringやnumberといったプリミティブな型を起点として、Product Types (直積型 / AND) と Sum Types (直和型 / OR) を駆使してあらゆる型を組み上げていく仕組みのこと
  • フラグで表現するのではなく型で表現する
    • e.g. isValidatedUserフラグではなくValidetedUser
  • Two-phase commitのようなコンテキストをまたいだトランザクションなんて君たちにはきっと扱いきれないんだから、何もしないか、せいぜい結果整合性で我慢しておきなさい
    • sagaという失敗管理のためのパターンもあるよ
  • トータル関数 / Total Functionsとは、エラーなども含めた全ての起こり得る事象が、関数のシグネチャに網羅的に記載されている関数のこと
  • 依存性の注入はカリー化部分適用により行う
    • (F#では全ての関数がデフォルトですべてカリー化されていることに衝撃を受けた)
// TSで書くとこんなイメージ
type ValidateOrder =
  (CheckProductCodeExists: Function) => // 依存
  (CheckAddressExists: Function) => // 依存
  (UnvalidatedOrder: object) => // 入力
  ValidatedOrder // 出力
  • シグネチャの異なる2つの関数をつなげるために、出力を入力を最小公倍数にそろえる行為をLiftingという
  • 複雑な判定をする類のロジックはActive Patternを使うことで保守性・可読性・堅牢性を向上させられる
  • ビジネスルールのの出力(e.g. 送料無料)だけをモデル化してはダメ。ルールへの入力(isVipUser)をモデル化し、それをもとに算定をして、出力せよ。

感想・疑問点など

  • TypeScriptにはmatchやResult型、result構文がない中で、どの程度関数型プログラミングを効率的に書けるのか
    • Result型はneverthrowあたりを活用すればなんとかなりそう
    • 先駆者によると、Result型がネストしたときは辛いらしい
      • F#のlet!result構文、Rustの?のような構文がTSにもあればいいけど、実装されることは一生なさそう
    • どこまでやれるのか、やるべきなのかの判断がとても重要になりそう
      • 以前チャレンジしたときは単に読みづらくなっただけで結局シンプルな記法に戻した経験あり。ドメインエンティティとそのロジックが鬼のようにたくさんあるプロダクトだと効能が高まるのだろう、しらんけれど.com
  • 1つのトランザクションでは1つの集約のみを更新するのが原則と書いてあったがそんなこと現実的に可能??と思ってしまった。心構えが間違っているのかもしれない。
  • コンテキストを分けるにあたってマイクロサービスに分ける必要はなくて別にモノリスでもかまわないとの記載があったが、イベントを伝播させていくためのコードをどう書くかイメージが湧かなかったので、この世の何処かにサンプルコードが落ちていてほしい

以上。モナドの意味は結局わからんかったが読んで良かった。

やはり英文だと脳内メモリ少ないワシでも負担少なめで読める気がする。語順の問題?翻訳の問題?
やはり英文だと脳内メモリ少ないワシでも負担少なめで読める気がする。語順の問題?翻訳の問題?