こちらのイベントで発表した資料です。 『ドメイン駆動設計を導入するためにやったこと』 https://modeling-how-to-learn.connpass.com/event/229811/
巨大レガシーシステムの戦略評価とリファクタリングにおけるDDDの活用事例2022/01/17(月)READYFOR株式会社ミノ駆動
View Slide
お品書き● 自己紹介● READYFOR株式会社の事業概要● DDD導入準備:僕の入社● 導入理由&取り組み1:開発費用対効果の向上● 導入理由&取り組み2:リファクタリング● 取り組み3:変更容易性勉強会
自己紹介 ミノ駆動READYFOR株式会社のバックエンドエンジニア。リファクタリング専門で仕事してます。その他アーキテクチャ設計、設計支援(アドバイスや評価)、プロセス改善など、品質向上にかかる様々な業務を遂行しています。10年間大手電機で組み込み系やってきて、3年前にWeb系に移籍。依然Web系の知識不足でハンデを感じており、ギャップを埋めるべく日々邁進中。
Twitterに不定期でクソコード動画を投稿してます
クソコードを退治しに行くゲームも作りました『バグハンター2 REBOOT』https://game.nicovideo.jp/atsumaru/games/gm22047無料。PC、スマホでプレイ可。
設計技術書を出版します● クソコードアンチパターン駆動の設計技術書です。● 以下を解説する技術書です。○ 変更容易性を貶める悪しきコードが抱える課題○ 気をつけていても、ついつい陥りがちなポイント○ 改善に導くための設計方法と考え方● サンプルコードを膨大に用意しております。400ページover。● 技術評論社様より今春全国出版予定。ご期待くださいませ。● (※なお、前ページのゲームは本書の副教材的な位置づけです)
READYFOR株式会社の事業概要クラウドファンディング事業。寄附、資金調達を募るサービスです。サービス上で実行者が寄附を呼びかけ、支援者が寄附金を支援します。
取り組み準備:僕の入社自体がDDD導入弊社READYFORのEngineering Manager「ミノ駆動さんを招き入れること自体がDDDの導入」。オブジェクト指向カンファレンス2020では、僕を捕まえることを目論んで、僕の設計思想を意識した登壇発表資料まで作成したそうな。当日は僕も登壇発表していたが、タイミングが合わず、物理的な僕が誰なのか分からなくて、このときは捕まえられなかったとのこと。のちにTwitterで相互フォローになった直後、即ナンパされて入社するに至る。
導入理由1:コアドメインを見定め、開発費用対効果を高めるため巨大なシステムは、システムが解決する事業領域がとても広い。一方で開発費用は有限。システムの全てに開発コストをかけられない。コストの集中的投資に値する、競争優位性を発揮できる事業領域がどこかを見定めなければならない。それに対し、どこが中心的な事業領域なのか、そこにどういうシステムを立てるべきなのか、ほとんど整理されていなかった。
事業の中心的領域「コアドメイン」競争優位性を発揮し、最も価値を付加すべき事業領域を「コアドメイン」と呼ぶ。DDDのいの一番に登場する、超重要概念。DDDの真の主人公(DDDで登場する設計パターンはコアドメインの価値向上のための手段のひとつに過ぎない)。どこがコアドメインかを分析し、システム開発の費用対効果を高めるためにDDDを導入した。分析にはコンテキストマップを使った。
凡例:娯楽を楽しみたい顧客を整理したい買い物したい問題領域と解決領域サッカー動画配信サービスTVゲーム紙Excel方眼紙CRMシステムコンビニECサイト移動販売車問題領域解決領域
モノリシックシステムは複数の問題領域にまたがりがち配送 注文在庫モノリシックなECサイトモデルの解釈が混乱し、変更容易性が低下しやすい。
事業領域が不明、どのシステムと関係するかも不明???領域???領域???領域システムAシステムBシステムC【課題】弊社の場合、どんな事業領域があるのか具体的に整理されておらず、不明瞭であった。また、どの事業領域にどのシステムが対応するのかも分かっていなかった。このような状態でコアドメインを見定めるのは困難。
取り組んだことドメインエキスパートと思わしき複数の関係者にインタビューを実施。● 解決したい課題● 目的● ルール、どんな世界観か● 登場概念と、概念に対する考え方 etc…これらが明瞭に異なる境界が、問題領域(事業領域)の境界となる。
事業領域を明確化し、コアドメインを特定できた事業領域C 事業領域E事業領域A 事業領域B事業領域D(コアドメイン)システムAシステムBシステムC手作業ここは事業領域ごとにシステムを分離しようここに集中投資しよう。変更容易性も高めていこう。手作業で非効率だ。コアにも関係するし、この手作業をシステム化しよう。
苦戦したこと:莫大な情報量コンテキストマップを作る上で、いろんな部署に話を聞きに行ったり、資料を読み漁ったり…。様々な情報を頭に叩き込んだ上で、問題領域と解決領域(システム)の関係を整理していかなければならなかった。脳にものすごい負荷がかかって、毎日爆発しそうだった。半泣きで仕事してた。入社したて&リモートワークだったので有識者が誰か分からず、Slack上で「有識者は誰だああああああ!!!!!」と絶叫巡回していた時期もあった。大量の情報整理には、もっと人的リソースが必要であることが分かった。
導入理由2:巨大レガシーシステムの技術的負債解消巨大なRailsアプリの技術的負債により変更容易性に課題。ローンチしてから約10年モノのレガシーシステム。1つのモデルが複数の意味を持ってしまってFatになっていた。Rails-wayだけでロジックを整理するのは限界。そこで、上手くリファクタリングしたり、そもそも負債を作り込まなない開発を進めるために、DDDの設計思想を導入する流れへ。
エンジニア全体の納得感醸成が課題Rails-wayから外れたアーキテクチャに変えていく方針。僕一人がDDDベースでリファクタしても、エンジニア全体に意図が理解されていなければ混乱を招く。また、他のエンジニアさんがRails-wayだけに固執して実装を進められると、負債がなかなか減らなかったり、逆に負債を作り込まれてしまう懸念もある。したがって全体で負債を低減していくためには、エンジニア全体にDDDの利点を周知し、納得感を醸成する必要がある。
【余談】DDDを覚えたての頃のぼく今からX年前、ずっと以前の職場にてぼく「DDDすごいんですよ!DDDやりましょうよ!」上司「何がすごいのかね?どんな課題を解決するの?」ぼく「……」上司「説明できないものを採用しようというわけ?」ぼく「……」こういう失敗があって、DDDとはなんぞやを学び直すキッカケになった。
課題が導入技術と合致していることが重要あらゆる技術は、何らかの課題を解決するために編み出される。課題と一致していなければ、導入する価値がない(例えばグラフィック性能を向上したいのにキーボードを買ってくる人がいるだろうか?)。DDDの導入も同様に、現場の課題が何であって、DDDによりどう解決されるのかを結びつけて説明する必要がある。特にRailsはDDDとの親和性が低いので、どう乗り越えるかを説明する必要があった。
説明したことDDDとは、コアドメインの価値を高め、長期的に成長体質にする設計思想。具体的には、ソフトウェアの機能性と変更容易性の向上を促進する。課題 解決方法DBとの密結合 RepositoryでDB知識、つまりActiveRecordを隔離FatModel、概念の混乱 コンテキストやユビキタス言語、VOやAggregateでドメイン概念を整理全部DDDでやるのか コアドメインや、負債が特に酷い箇所に絞ってDDDでやる。それ以外はRails-wayでも良い。
アーキテクチャDomainActiveRecordControllerViewInfrastructureUsecase
上手くいった/いってること皆さん負債に困っていたので、割とすんなり受け入れられた。「巨大モデルが複数の意味持ってしまって混乱してるから、意味の違う概念単位で分割する考えに賛成」という反応が多かった。新規にコードを書くとき、DDDベースで設計実装する人が少しずつ増え始めた。僕が適宜助言しているのもあって、要点をおさえた設計ができている。プロダクションコードの増加に対して、負債の絶対量はほぼ変動なし。今後低減に向かうことを期待。
というSlackスタンプが爆誕しました
苦労してること:Rails-wayとにかくRailsの仕組みが邪魔でしょうがない。ActiveRecordを中心に便利機能が集約しているために、ActiveRecordから離れようとすると凄まじい引力で引き戻されそうになる。本当はpureなRubyクラスだけでドメインオブジェクトを構成したいが、どうしてもRailsと妥協しなければならない局面がある。そうした中でもActiveRecordを上手くRepositoryに隠蔽してpureなドメインオブジェクトを設計できると、嬉しさのあまり小躍りしたくなる。
苦労してること:Ruby型のサポートがないので、依存関係を正確に追跡できない。リファクタリング効率がどうしても落ちる。Rubyに比べたら静的型付け言語のリファクタリングなんてヌルゲーです(暴論)そんな中でもリファクタして整理していくと、自分がリファクタした箇所だけ追跡性が静的型付け並みに向上する。
導入取り組み:変更容易性勉強会ハンズオン形式の社内勉強会。増田さんの『現場で役立つシステム設計の原則』を参考テキストとして使用。
勉強会の流れ● 開始前までに所定のページを予め読んでおく。例えばFirst Class Collectionパターンのページを読んでおく。● コミュニケーションツールSpatialChatを使用(次ページで解説)● SpatialChat上でグループに分かれる。● 実際の製品コードから、First Class Collectionとして設計できそうなコードを探す。● スクラッチで、まっさらな状態からFirst Class Collectionとして設計実装し直してみる。● 各グループごとに成果発表して知見を共有、議論。
SpatialChat(スペチャ)を利用同じ部屋で、画面共有が複数可能。他のグループがどんな実装をしてるのか様子を見れる。お互い刺激になる。