ravelll の日記

よしなに

エリック・エヴァンスのドメイン駆動設計 1章メモ

今週から社内で読書会が開かれることになった。基本的には事前に読んでくるスタイルの会ということで第1回の範囲となる1章を読んだので、雑に取ったメモを放流。

1章 知識を噛み砕く

  • ドメイン知識が無い状態でもの(PCB)を作った体験
  • ドメインエキスパート(PCB回路設計者)がソフトウェアが達成すべきものをよく知っているわけではない
  • ドメインエキスパートと話し合う中で語彙を研鑽する
    • 用語の不一致を正す、使うべき言葉をドメインエキスパートが学ぶ
  • 処理の流れ(モデル)を一緒に書いていくやり方が良い?
    • 登場人物の名前を知る
    • 登場人物の関係を知る
    • 処理の名前を知る
    • 処理の概要・目的を知る
  • ドメインエキスパートとの議論においてソフトウェアの詳細に立ち入り過ぎないよう気をつけるべきっぽい
    • "すみません、詳細に立ち入りすぎました"
  • ドメインモデルを注意深く作成することで本質的な処理を見つけやすくなる?
    • "その後ほんの数日のうちに〜実際に計算したことには変わりない"
  • ドメインエキスパートと一緒に図を作ったことで、あるドメインの複雑さの中で今回つくる機能が持たねばならない部分がどこなのか、を開発者単体で考えたときと比べて精度高く知った状態で開発に入ることができるのでは
    • 複雑さを見誤るとどんなに設計が良くても負債になりそう
    • 例えば Web アプリだと DB の設計を含むくらい機能開発をするときにはミスると辛いしそこを境界線として特に注意深くドメインエキスパートとコミュニケーション取りながら作る、みたくすると良いのかもしれない
  • ドメインエキスパートと一緒に図を作ることでソフトウェアの構造をドメインエキスパートより理解できるようになる
    • その結果、ドメインエキスパートがソフトウェア開発に協力的になる、という流れがある
    • ドメインエキスパートとの距離を感じたら大まかな設計を一緒にやってみることから始めると良いのかな
    • ソフトウェア開発者がドメインエキスパートとコミュニケーションを取るフレームワークとなった
      • 完全にいい話
  • ドメインエキスパートと一緒にモデルを作成しソフトウェアを開発することで、ドメイン知識がソフトウェアに組み込まれる
  • 本ではドメインエキスパートがオブジェクト間の相互作用を提示するまでになってるけどそれを望むのはきつそう
  • 顧客が本当に求めているものを協力して探すには、やはりモデルを一緒に作るのが良さそうに感じた
    • "モデルを改良すると、コードも一緒に進化した。数カ月後、PCB 技術者は自分たちの期待を上回る、機能豊富なツールを手にしていた。"

効果的なモデリングの要素

  • 筆者によるこの話についてこれが成功の秘訣だったリスト
    • モデルと実装を結びつけること
    • モデルに基づいて言語を洗練させること
      • 最初辛い(主にドメインエキスパートが)けど相互にモデルを理解できるようにしておくことでモデルの構造と矛盾しない思考で議論することができるようになった
    • 知識豊富なモデルを開発すること
      • モデルは単なるデータスキーマではなく、複雑な問題を解決する振る舞いと守るべきルールがある。クゥ〜ッ
    • モデルを蒸留すること
      • 蒸留 = 本質的でない概念を切り捨てる
    • ブレインストーミングと実験をすること
      • モデルの形を色々と書いてみては議論することで使えるか調べた
      • このときに会話がぎこちない = このモデルはダメそうという判断ができた
  • (ravelll)開発者がドメインエキスパートのとき DDD を利用する利点はあるのか
    • ユーザーを登場人物に含めて間接的にモデルについて議論する、と考えるとモデルを洗練させ実装と一致させる狙いで利用する意味が十分ありそう
    • DDD が良いのは翻訳による情報の欠如や時間的なロス、人間関係の改善とするなら、ユーザーと直接話すことはなく開発者がただ議論するだけなら翻訳のオーバーヘッドも小さそうなので実は効果的ではない?

知識の噛み砕き

  • "噛み砕く" = それの根底にある意味を知るプロセス
  • "ドメインモデルを噛み砕く"ということ
    • 情報の流れを掬ってその重要な意味の大部分を理解できる抽象的なモデルを見つけること
  • 知識の噛み砕きは一人で行うものではなく、開発者とドメインエキスパートで行う
    • 大抵は開発者が率いる
  • 知識噛み砕きプロセスの失敗事例
    • (1.) ウォーターフォールでの流れ
      • ビジネスエキスパートがアナリストに話をする
      • アナリストが情報を噛み砕き抽象化する
      • ソフトウェアエンジニアがそれを実装する
        • この流れにはフィードバックのタイミングがない
        • アナリストが基にするのはビジネスエキスパートの話だけ
    • (2.) イテレーティブにやってるけど抽象化してなくて知識が積み上がらない
      • 何を作るかビジネスエキスパートに聞いて実装し、終わったら提示する
      • "何を作るか" だけに集中するとモデルの蒸留が行われなくてダメそう
      • "そうしたやり方でも(snip)既存機能の必然的な帰結として強力な新機能が現れるという段階には、決して到達することがない。"
        • ゴールド・エクスペリエンス・レクイエム!!
      • 抽象化もドメインエキスパートとの共同作業なしに行うとドメインエキスパートの考えと乖離してしまう
      • "チームメンバ間のやりとりは、メンバ全員がモデルを一緒にかみ砕くことで変化する。" いい話っぽい
      • ドメインモデルを絶えず改良すると開発者はビジネスにおける重要な原理を習得するよう強いられる、というのがちょっとわかってない
        • ドメインモデルを絶えず改良すること = ドメインエキスパートと絶えずコミュニケーションを取ることで、
        • 重要な原理を習得していないことはドメインエキスパートとコミュニケーションを取ってモデルを作ることを妨げるから?
  • うまく知識をチームが噛み砕けるとモデルはビジネスの深い知識を反映したものになる
    • "改善されるにつれて、モデルは、プロジェクトの中を流れ続ける情報を体系化するためのツールとなっていく。"

継続的学習

  • 生産的なチームを知識を意識的に育てる
    • 十分な知識が無いことを認識することはしばしば難しい
    • 知識はメンバーの入れ替えやアウトソーシング等によって流出する
  • "技術的な知識" って例えば gRPC について知る、みたいな話?
  • 知識があると知識の噛み砕きをよりうまくできるようになる
  • 例えば PCB の事例について学んだところ
    • (エキスパートとの対話を通じて)アプリケーションに関連する重要な概念の理解
    • 構築している内容がただしいかどうかのチェックを行うこと
  • 大事なのは共同作業によって作成されたモデルが残ることではなく知識の噛み砕きのプロセスを起こさせること
    • 知識の噛み砕きが行われることで以後の作業がより効果的になる

知識豊富な設計

  • 設計やリファクタリングはモデルの変化を主軸として行われるもの
    • 逆に言えば、開発者はモデルの変化に機敏に対応できる設計にし、実際に追従していかねばならない
  • 存在しているエンティティやコードを超えて、相互作用やビジネスルールに注目する
    • コードは合っているがビジネスルールとして矛盾している、ということに気づける
    • この辺コードレビューしてるとどうやったら気付けるのかな〜とよくなる…
      • 普段から背景となるビジネスルールまでを考えてコードを読み書きすることで一歩抽象度の高いレビューができるようになる?
  • 人間は自身が触れている世界のプロセスを処理する中おきるギャップを思考によって無意識に調整・補完している
    • そんなことはソフトウェアにできないので、知識をちゃんと噛み砕いて具体化させ、実装したり切り捨てたりする
  • 貨物船の例
    • あるモデルが満たすべきルールを相互作用のプロセスに押し込んでいる
      • これではドメインエキスパートがコード(エンティティを指している?)を読んでも検証できない
    • 知らない人が要求定義とコードとを結びつけるのが困難になる
    • この例ではオーバーブッキングポリシーを別クラスとして表現しているけど、これはポリシーは船舶にも荷物にも紐づくものではなくビジネスとして存在する"知識"であるから独立したクラスとして表現されるのが適当、という判断?
      • "知識を確固たるものにして共有するのに使えることを示すために用いた" とある

深いモデル

  • アプリケーション作ってるときにそれを誰がどう使っているのかを勝手に思い込んでいらない機能を作る、というのは超あるあるという感じ