天の月

ソフトウェア開発をしていく上での悩み, 考えたこと, 学びを書いてきます

イミュータブルでゆこうに参加してきた

modeling-how-to-learn.connpass.com

今日はこちらのイベントに参加してきたので、会の様子と感想を書いていこうと思います。

会で話されていたこと

イベント資料

資料は以下のページにまとめられています。

modeling-how-to-learn.connpass.com

イミュータブルデータモデルの極意~川島義隆さん~

30分の発表だと思っていたら60分の発表であることに会の1時間前くらいに気が付いたそうです

最初に川島さんからの発表がありました。以下に内容をまとめていきます。

川島さんの問題意識~Division into cases~

川島さんが持っている問題意識として、数学の問題を解く時には場合分けを適切にするのに、ソフトウェアの話になると途端に曖昧な場合分けをすることがあるというお話でした。
例えば、数学でax=1という方程式が出てくれば、aが0かどうかで場合分けをするのに、ソフトウェアだと、「XXXという技術プラクティスは、時と場合によって使える時と使えない時がありますよね」位の粒度で話が終わってしまうことが多いという話でした。

Dataの場合分け

川島さんは、今回のプレゼンテーションではData*1について、「時と場合によって扱いが変わるよね」ではない場合分けをしていってくれました。

具体的に言うと、Dataは、Event*2とResource*3に場合分けができるというお話でした。

EventとResourceの関係性

次にEventとResourceの関係性について、こちらも場合分けしてそれぞれにおける特徴をお話してくれました。

まず、EventとResourceの関係性については、EventはResourceを生成/更新/削除する役割があるため、Eventの7W3H(When, Where, Who, With Whom, Whom, What, Why, How, How many, How much)がResourceに対して関連を持つというお話がありました。

次に、ResourceとResourceの関係性についてお話がありました。
この場合は、Resource同士に依存関係があるか?とライフサイクルをそろえるべきか?という観点でさらに場合分けできるということで、一方が存在しないならばもう一方のResourceも存在してはいけないケース*4や、Resource同士が非依存であるケース*5があるというお話でした。

最後に、EventとEventの関係性について話があり、この関係性の特徴としては、Eventの時系列が厳密であるという話がありました。*6

EventとResourceのサブタイプ

Resourceのサブタイプを考える際には「区分」を意識することが大切で、Eventのサブタイプを考える際にはイベント全体の繋がり(=ロングタームイベント)が大切だというお話がありました。

Resource同士の関連付けをする際のコツ

例えば部門と社員で所属という関連がある際、この所属に関するEventは関連とは別に識別することが大切だというお話がありました*7

記録として残すEvent, 残さないEvent

Eventは闇雲に記録するものではないので、更新日時を思考停止で作るのは止めて欲しい*8という話がありました。

Eventを残すのは、お金を産む or 記録がないとお金を失うリスクがあるものに限定しておく必要があり、残すと決めた場合は絶対に変更してはいけないということでした。(変更する=事実を失うことになるため)

ドメイン駆動設計とイミュータブルデータモデルの素敵な関係~増田亨さん~

続いて、増田さんがイミュータブル*9になぜ拘るのか?というお話をしてくれました。

イミュータブルについての厳格性

はじめに、イミュータブルについての厳格性について対比をしてくれました。
ざっくり言うと以下のように分かれているということです。

  • Evans本→できればイミュータブル
  • セキュア・バイ・デザイン→できるだけイミュータブル
  • 増田さん→必ずイミュータブル
必ずイミュータブルにする際の設計パターン

第一に、「閉じた操作」が紹介されました。
具体例で言うと、JavaBigdecimal#add(BigDecimal other)のように、メソッドの引数の型とreturnする型がそのクラスの型に閉じるような操作のことを指しているということでした。

第二に、「withメソッドパターン」が紹介されました。
これは要するにsetterを使ってオブジェクトの状態変化するのを防ぐというパターンで、具体例としては、LocalDate#withMonth(int month)のように別のオブジェクトを返す例が挙げられていました。

最後に、「イベントリポジトリ・集約ファクトリ」が紹介されました。
これは、事実の記録と集約の構築を非対称にするというお話で、このパターンを取ることで、同じ事実からは同じ結果が必ず導かれるようになり、ビジネスルールの一貫性が担保されるというお話でした。

増田さんがイミュータブルに拘る理由

クラウドの台頭により、並行処理が当たり前になってきたという時代背景が大きいということです。
並行処理をする際には、オブジェクトの同期や一貫性について考えるのが当たり前なので、その際にシンプルで分かりやすいイミュータブルは、非常に魅力的に映っているということでした。

ドメインイベントの観点から再考するソフトウェア設計~かとじゅんさん~

最後に、かとじゅんさんからドメインイベントについてのお話がありました。

ドメインイベントとは

ドメインイベントは過去に起きたドメイン上の出来事を指しており、イミュータブルである前提(=git rebase -iできない前提)があるというお話でした。

よくある誤解として、実装がES(Event Sourcing)じゃないシステムでは使えないという話があるようですが、分析ツールとしても有用な考え方なので、自分の現場では使えない考え方だと諦めないで欲しいということでした。

ドメインイベントはなぜ有用か

コトに注目することで、ドメイン知識にフォーカスを当てやすくなり*10、ヒトやモノと違って全体の関係が整理されやすくなるというメリットが挙げられていました。

また、この有用性を活用した例として、Event Stormingが挙げられていました。*11

ドメインイベントをどう利用するか

ドメインイベントを利用する方法として、今回の発表ではES(Event Sourcing)が紹介されていました。

ESを使うことで、スケーラビリティを確保できたり*12、並行処理をする際に非同期連携が取れやすくなるということです。
なお、レイテンシ悪化といったデメリットもあるとのことですが、こういったデメリットはソリューションでカバーできるというお話でした。

プログラミングモデル

具体的なプログラミングモデルとしてCRUDモデル, ESモデル, AKKA-ESモデルが紹介されました。

CRUDモデルは集約がイミュータブルにできる反面、OOPLと組み合わせると集約を小さくしつつ普遍条件を維持しながらプログラミングする必要がある点に注意が必要ということでした。

ESモデルでは、イベントの大きさによってはレイテンシが悪化したりデータ競合を防ぐ仕組みづくりが必要になるため、素直な実装をしてしまうとCRUDモデルよりも更にデメリットが目立ちやすいということでした。

そんな2つのモデル説明を受けて最後に紹介されたAkka-ESモデルでは、ワークロードが有効である限りはオブジェクトがランタイム上に保存され、永続化されるのはワークロードの終了となるため、DBとのI/O負荷を軽減させることができるというお話が紹介されました。(プレゼンの構成はあると思いますが、Akkaのすごさを実感しました)

座談会

最後に登壇された3人で座談会をしていきました。
お三方のお話はどれも現場で経験してきた苦い思い出が基になっており、リアルな体験談が聴けてとっても楽しかったです。

主な話題としては、お三方がイミュータブルに魅力を感じるようになった経緯が聴けました。以下、お三方それぞれのエピソードを書いていきます。

川島さん

まず、仕事でモデリング研修している時に佐藤正美さんと出逢い、DBにおけるイミュータブルの重要性を実感したということでした。
その後は、羽生さんの楽々ERDレッスン*13で、「Eventはお金を生むから大事なんだ」という話に感動し、以降DB設計する際やモデリングする際には、イミュータブルを一つのキーワードとして考えるようになったということでした。

さらにプログラミングの方でも、clojure*14を学ぶ中でイミュータビリティに対してのフォーカスが強さに関心を持ち、現場で使える技術(変更が安全な技術)という点もあり、更にのめり込んでいったということでした。

かとじゅんさん

羽生さんの楽々ERDレッスンで、Eventの見分け方どうしたらいいのか?という問いに対して、「"~する"で意味が通ればEventだ」というとっても分かりやすい定義に出逢い、ここでまずEventという捉え方に対して興味を持ったということでした。

また、プログラミングの観点で言うと、かとじゅんさんは最初Javaを使っていたということで、愛読書だったEffective javaにあった「イミュータブルに基本せよ」からイミュータブルへのフォーカスはスタートしたということでした。
その後は、「ミュータブルにするのは例外ケース」「変数定義をvarで書いたら負け」と言われていたScalaに触れていく中で徐々にイミュータブルの重要性を実感し、純粋関数の組み合わせから生まれる予測可能性を大事にするようになったということでした。

増田さん

増田さんは大前提として、「どんなにいい考え方でも現場で使えないのは辛い」という考え方を持っていたということでした。

その考えを持っていた中、Haskellに出会い、そこで外部との副作用含めてラッピングしてしまうという発想から生まれるコンパイル通りさえすればいいという安心感に感動したということです。
その後は、HaskellでのWebプログラミングにチャレンジしていたものの、エコシステムがなさすぎる点と、チーム開発をする際にHaskellだと知識のレベルが揃わずきついという問題を抱え、徐々に今の(Javaで)イミュータブルを絶対とするプログラミングスタイルに辿り着いたということでした。
また、Java8で日時系APIがミュータブルからイミュータブルに変更されたときに扱いやすさが格段に上がったという体験や、CPUが贅沢に使えるようになった(≒メモリ無限前提で考えてもいいようになった)というパラダイムシフトも、増田さんのプログラミングスタイルに大きな影響を与えたそうです。

全体を通した感想

豪華なお三方の講演&座談会が聴ける超濃密な2時間半で、とても充実した時間を過ごすことができました。

色々な現場に携わっているお三方が共通してみてきた地獄や、共通して持たれている「現場で使える知識を大切にする」という考え方が印象的で、特に「現場で使える知識を大切にする」という考え方は今後技術を学んでいく上で心にとめていきたいと思いました。

コメントしている方々の練度もとっても高くて、(途中倒れていましたが笑)とにかく楽しかったです!

*1:事実。この事実を加工あるいは選択したものが知識となる

*2:コト。日時属性を持っているためData同士は非対称的である。あくまでも一時点のスナップショットでしかないため、属性が変わることはない

*3:モノ。日時属性を持たないためData同士は対照的である。ライフサイクルがあるため、PKなどによって属性が変化していても同じDataである旨を表現する必要がある

*4:例えば国と都道府県など

*5:書籍とユーザなど

*6:請求書の発行Eventは注文の発注Eventよりも先に起きたらおかしい

*7:例えば「配属」というEventを作成する

*8:廃藩置県する人でないなら、都道府県テーブルに更新日時はいらない

*9:ただ、増田さんはイミュータブルという言葉自体はあまり使っておらず、変更容易性、整合性といったキーワードの文脈で使っている

*10:コトに関連する業務知識を理解することでドメインの整理ができるため

*11:Event Stormingでは、ステークホルダー全員がワークをするため、闇雲にEventを作るのが避けられるというメリットもある

*12:処理を追記するだけなので更新を考える時と比較して考えることが少ない

*13:佐藤正美さんに弟子入りしたけど決別して書かれた本らしいですww

*14:基本的にはイミュータブルなデータしかない