初の輪読会で、Domain Modeling Made Functional を読んでみた
はじめに
エンジニアの下村です。
以前、ブルーモでDomain Modeling Made Functional の輪読会を開催しました。書籍の内容からも輪読会そのものからも、多くの学びを得られたため紹介いたします。
先に要点をまとめると、以下のようになります。
参加者が事前に対象範囲を読んだ上で開催する形式は良かった
複雑なロジックを実装する際にうまく整理できていなかったコードをより良くするためのヒントをたくさん得られる良書だった
輪読会は個人のスキルアップのみではなく、プロダクトの品質向上やチームの生産性向上に繋がると実感した
なお、書籍の紹介や要約を意図した内容ではなく、あくまで輪読会についての記事であることにご留意ください。
輪読会の紹介
輪読会のきっかけ
6月に正社員として入社した葛西さんのtimesがきっかけで、輪読会の開催が決定しました。
他の参加者を社内で募り、新卒エンジニアの安田さんと3人で読み進めていくこととなりました。
これは余談ですが、対象書籍について邦訳書があるにもかかわらず洋題で書いているのは、決して格好をつけたいためではありません。開催決定時点では洋書しかなく、参加者の1人がすでに洋書を購入後に邦訳書発売予定であることを知ったからです。
輪読会の形式
まずは実践的な話として、輪読会をどのように実施したのかについて説明します。
輪読会は、事前に対象範囲を読んでくる形式で実施しました。会は30分で、要約の担当者が対象範囲の要約を15分程度で発表後、持ち寄った議題について議論を行う流れで進めました。
また、会の進行に対して、要約者、司会進行、書記の役割を事前に用意しました。要約者は、事前に対象範囲の要約を次回の議事録に記載しておき、会では要約箇所について説明を行います。司会進行は、主に議論で話を適切な人に振ったり、時間を調整したりする役割です。書記は、議論の内容を議事録に記載します。輪読会の参加メンバーがちょうど3人いたので、各回で役割を回しながら進めました。
自分は輪読会の開催おろか参加すら初めてだったため、手探りで役割を決めたものの、結局最初から最後までこの方式を採用しました。何かを実装するような書籍なら別かもしれませんが、本書の場合はもう一度やり直すとしても、だいたいこの形式で良いかなと考えています。
輪読会の反省
輪読会が完了した後には、輪読会全体の振り返りを行いました。そこで輪読会に対して出てきた改善案についても紹介いたします。
まずは、要約の程度です。どれくらいの情報を載せるか基準がなかったため、重たい章が対象のときはかなり気合いの入った要約となり、要約の紹介で20分程度の時間を使ってしまうこともありました。次回以降は、要約の紹介時間を事前に定めておいたり、要約の基準を設けるなどすればよかったと感じています。例えば、紹介時間は15分、要約の基準については箇条書きで章の流れを説明できれば良いなどとしても良いかもしれません。
次に、要約担当者の負担が大きすぎるという課題感もありました。全員が書籍を読んだ上で輪読会に臨んでいる前提のため、ここの負荷は極力減らしたほうがよく、生成AIによる要約で事足りるのではないか?という提案がありました。要約の目的を、記載内容を思い出せるようにするとするなら生成AIで十分だと考えられるため、今後はその方針で進めることになるかもしれません。
最後は、当たり前の話でもあるのですが、対象書籍の選定の難易度の高さについてです。今回の書籍はとても良い選択だったと参加者全員の意見が一致しましたが、毎回、輪読会対象として優れた書籍を選べるかどうか懸念があります。これについては、明確な手はないと結論づけ、毎回の選定には気を遣う必要があると全員で合意するのみとなりました。次回以降の輪読会などで知見が溜まったら、また共有の場を設けたいと思います。
学び
書籍から得られたこと
書籍『Domain Modeling Made Functional』から得た学びを一言でまとめると、「我々はまだ本当の型の威力を知らない」ということです。テストしやすく改修もしやすいコードを書くために、まだまだ型とコンパイラを活用しきれていないと痛感しました。
書籍は私たちに多くの知見をあたえてくれたのですが、そのうち最も印象深かった一つを取り上げて紹介します。
私たちのドメインモデルは、一つの大きな概念を一つのモデルに落とし込み、一つの型で表現していました。例えば、我々のアプリでは顧客との取引なる概念を持っているので、それに呼応して取引というモデルを設計して、取引という型を実装していました。一方で、取引には入金や出金などいくつかの種類 (trade_type) があります。また、取引はいくつもの段階を踏んで随時処理がなされていくため、今がどの段階なのかの情報 (trade_status) も持っています。これらについては取引の型の内部で表現するようなモデルですが、それぞれの種別や状態を型として表現することで、より頑健で進化させやすい実装になると考えるようになりました。
既存のモデルで1番課題に感じていたのは、あり得ない状態のインスタンスを防ぎきれないことでした。例えば、取引がある段階になると確定金額がデータとしてモデルに含められるようになります。一つのモデルでこれを表現すると、確定金額の有無はモデルの中の条件分岐で処理をしていくことになります。具体的には確定金額の設定時には、それまで値が設定されていなかったことを確認し、その後も取引の段階と値の存在を確認した上で処理をしていくことになります。このような処理がコード中に大量に必要であり、開発者の認知もしくはテストのカバレッジから漏れるとバグが生まれてしまう状況でした。
先述した解決策である、それぞれを型として分けて表現する方針を取った場合、確定額は必要な型にしか定義する必要がありません。そのため、あるかないかわからない属性ではなく、絶対に存在する属性として表現することができます。既存のペインポイントだった確認はコンストラクタにまとめることができて、一気にコードの見通しが良くなるかつ、バグも生じにくいコードにすることができます。
このように、Domain Modeling Made Functionalは型を使ったモデルの表現方法について多彩な知見を我々に与えてくれました。
輪読会の実施から得られたこと
最後に、書籍を輪読会の形式でインプットすることによって得られたメリットを二つ紹介します。
少しイメージして欲しいのですが、1人で書籍を読み、書籍の知識がプロダクトに活かせる可能性を見出したときに、実際に実装に至るまでどのくらいのステップを踏む必要があるでしょうか?その知見の意図と、本当に有効であることを説明するための資料作成、それらを全体に共有した後での合意形成など、結構面倒だと感じませんか?
輪読会を起点にすることで、このステップを簡略化することができます。
まず、全員が同じ書籍を読んでいるため、知見の概要や意図、効果などを改めてまとめる必要がなくなります。そのため、合意形成に至るまでのステップが簡略化され、非常にスムーズに実装まで繋げることができます。これはどの輪読会でも言える汎用的な効果と考えています。
つまり、輪読会はただインプットを全員で行うだけでなく、その知見を活かすまでの流れがとても早くなるメリットがあります。
今回の輪読会では具体的に、先述した段階や種別に対して型を積極的に分ける方針への合意を行えました。この合意はすぐに活かされ、輪読会と同時期に行っていた新機能開発にはもうその内容が反映されていました。
もう一つのメリットは、個々人の思想を共有する場が作れることです。輪読会で議論を行うことで、各々が暗黙的に考えていた「コーディングはかくあるべきだ」という思想などが随所で表出しました。まず当人がアンコンシャスバイアスに気付けたことが良かったと感じています。ただし、的を外れたバイアスというものは今回出てこなかったので、バイアスを正すというよりも、そのバイアスを全員が知れたことが良かったポイントと考えています。例えば、それぞれ暗黙的に持っていた思想が共有の思想に昇華されたことで、レビューのコミュニケーションがスムーズになったり、全員が納得するリファクタリングの誘発を期待できたりするのではないかと思います。
特に可読性のような曖昧な概念については、通常の業務内で擦り合わせを行うことがほぼないため、業務から離れた議論の場を設けることで、お互いの考えを知ることができたことは非常に良い機会でした。
他にも、ピアプレッシャーにより洋書を読破できたなど様々なメリットがあり、これらは時間的拘束を凌駕する恩恵だと感じています。そのため、エンジニアチームでは今後も輪読会を続けていこうと考え、第二弾以降の輪読会も、つい先日実施しました。
まとめ
輪読会は単なるインプットの機会ではなく、生産性を向上させる機会にもなることを紹介しました。みなさまに輪読会の魅力が伝わっていれば幸いです。
ブルーモは積極採用中です!
興味とご経験に応じて、エンジニア、デザイナー、PdM、事業開発など多岐にわたるポジションの仕事をお任せします。
会社やポジションについて、もっと知りたい方は以下もご覧ください!