より早く高いアウトカムを実現するために、ソフトウェアの状態に向きあった結果モジュラモノリスと向き合い始めた

Date
December 20, 2022
Private

この記事について

今年半年をふりかえり、株式会社Spirのプロダクト開発で向き合い始めた、モジュラモノリス化に想いを馳せていきます。

この記事の一つ前に、プロダクトマネジメント全体に関して書かせていただきましたが、今回は記事内で触れた「Delivery」の中でとても重要になってくるソフトウェアに関して書き進めたいとおもいます。

ソフトウェアの状態がアウトカムに影響を与えるのか

モジュラモノリスの話に入る前に、そもそもアウトカムとソフトウェアの状態がどのように関係してくるのかから考えを書いていければと思います。

ここで書く「状態」は少し複雑で、現時点のソフトウェアに存在する「技術的負債」「既知・未知のバグ」や「Maintenability」「Security」などを始めとした品質に関する特性などを「状態」という言葉でまとめて意味しています。

この記事内では「状態」に関して細かく書く事は避けますが、どれだけアイデアが素晴らしくても大きすぎたり時間をかけ過ぎたりなど、顧客に届くまではまだ価値があるかないかわからない「在庫」の状態となります。更にアイデアとして素晴らしくても時間をかけた結果そのときにはハマらなかったり、顧客が求めていたものとは異なり受け入れられなかったりなど、結果アウトカムにつながらない事も起こりえると思います。そういった不確実性が高い状態だからこそ(意味ある単位で)小さく早くだして検証して育てて行くことが重要になってくると考えております。

前置きがながくなりましたが、例えばソフトウェアの状態が、Readableでは無く把握が困難だったり、Maintenabilityが低く複雑でどこに何をかけばいいかぐちゃぐちゃだったりすると、変更点を把握して、変更を実施するという1回1回のサイクルが遅くなるため、結果としてアウトカムを高めるために必要な検証サイクルを高速で回す事ができないためアウトカムを高める事に影響が大きくでてしまうと考えております。

品質と速度のトレードオフという観点に関して

ここでは少し「状態」に関しても深堀りをさせていただきます。よくSNSや様々な開発プロジェクトで見聞きする事が多い言葉として「スピードと品質のトレードオフ」があると思っています。

こちらに関しても色々書き出そうかと思いましたが、僕なんかが書くよりt_wadaさんのスライドを引用させていただくことが一番良いとおもいましたので、そちらにおまかせしようと思います。

書きたいことの殆どが、上記スライドで説明していただけておりましたので、こちらで引用とコメントだけで進めさせていただきます。 

image

(質とスピード(2022春版): https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition?slide=78 から引用)

image

(質とスピード(2022春版): https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition?slide=39 から引用)

つまり状態をより良くしていく事が最高の品質に繋がり、最高の品質が最高のスピードを生み出し続ける。そして最高のスピードが結果として最高の品質を生み出すことにもつながると信じております。ゼロから開発する状態ではないため、時間はかかるとは思っておりますが、私達はまず短期的には品質に向き合い続ける事で、徐々に徐々にスピードを高めるサイクルを目指していく考えです。

モジュラモノリスに向き合い始めるまでのSpirの状態

  • コードの責務違反、あるいは責務設計の不在
    • 例に上げると「repositoryってどこから呼び出していいのか?」という悩みが発生すると実装が遅くなる
  • 業務ドメインの境界がコードに現れておらず不明瞭
    • 「TeamのusecaseでUserRepository呼んでいいの?」みたいな悩み
    • あとは「TeamってUserとリレーションあるけど、TeamのドメインエンティティってUserのIDを持つの?実体を持つの?」など
    • 組織規模が大きくなったときにマイクロサービス化という手段を取りにくい
  • 技術的責任でレイヤーが分離されており異なる業務で同じコードに依存している状態
    • これは技術的責任ストラクチャが原因ではないですが、前述した責務設計がうまくワークしていなかった事で課題となってきております
    • image
  • そもそも設計に関しての議論が活発ではなかった
    • これはSpirの組織拡大速度が一つの原因ではありますがエンジニア2名体制から半年ほどで7名に拡大した事で2名の時は無くても問題なかったことが急激に問題となって現れたということでもあります。
  • テストに関しての作成コストが高い
    • 技術的責任で分離されているからではないですが、依存が複雑が故に依存先の依存先までmockをつくるとかDIするとか色々書くコード量が増えていました

などなどここだけでLT登壇とかできるかもしれませんが、Spirという事業や組織が急拡大した事で、当初は問題なかったことが大きな問題として現れ始めた形です。

なぜモジュラモノリスを選択することにしたのか

そもそもSpirは表から見える業務のほか、裏側でも様々な業務が行われております。

これまではモノリスという選択でしたが、もしかしたらマイクロサービス(モノレポ・マルチレポ)という選択肢もあるかもしれません。

※厳密にはFrontend(SPA)とBackendは同じリポジトリですので、モノレポという言葉が当てはまるかもしれませんが、今回はBackendにフォーカスを当てます。

前述した課題の解決を、今のSpirの組織や文化、メンバーで向き合うには、そしてちょっと先の未来も見据えるとしたら何がいいか考えた結果、今回はモノリスのまま責務を明確にして、より業務設計に集中していける形から初めていく事から始めよう。もし(本当にもし)デプロイも分離したり分ける方が好ましい状況になったらマイクロサービス化するなど検討しましょう。今は業務を明確にしてモジュールごとに開発できる状態にする事になりました。

以下は、これらの課題に対して社内のエンジニアからモジュラモノリスの提案が上がった際の声です。

  • 実装前に業務の分割が強制される
  • モジュールの独立性が高まるのでそれぞれが自由に構成を変えられる(今はほぼ全部同じ構成になってるけど)
  • 依存関係を可視化しやすい
  • でもデプロイは一つなので楽
  • モジュール境界をミスっても比較的変更しやすい

モジュラモノリス化の向き合いかた

モジュラモノリスをSpirとして考え始めたのは、2022/08/15ですので、今で4ヶ月目という所になります。

image

立ち上げ時期であれば最初からですので、「俺がモジュラモノリスだ」と言い切れるとおもいますが、弊社はもともとはモノリスではありますが、途中からモジュラモノリス化への移行を選択したので、まだまだ始まったばかりの状態です。

そのため弊社では以下のとおりモジュラモノリス化を進めております。

  1. バグやUX改善系以外の開発時(新しく向き合うMVPの機能開発時)に生み出されるコードはすべてモジュラモノリスを前提として議論・実装を行う
  2. 詳しくは組織編のブログで説明できればとおもいますが、モジュラモノリスを提案してくれたメンバーがプロダクト開発ではなく、Spirの開発全体がモジュラモノリス化を推進できる文化・状態を作る形でリードする役割としてコミット(社内ではDX Chapterと呼んでいます)
    1. 新しい開発時に業務整理やモジュール設計の議論に参加して壁打ちやリード
    2. 初期はドキュメントや勉強会(説明会)を通して何故モジュラモノリスなのか?などコンテキストをSyncしていく
    3. reactiveなイベントが無いタイミングでは、proactiveに既存のコードのモジュール化を検討して移行するなど、改善を実施

2番のDX Chapterは関しては組織としてモジュール化が当たり前になってきたタイミングで解散予定です。Chapterや現在の体制Squadに関しては改めて記事かさせていただきます。

そして現在

一つ前の向き合い方に書いたとおり、新しいところから新しく進めている事もあり、徐々にモジュールが育ち始めている状態です。また半年後などにその時点のスナップショットをお見せできればと思います。

image

We are hiring

Spirではこのようにプロダクトを通して顧客のアウトカムを高める続けるために、顧客課題に向き合う事はもちろんですが、より多くの顧客課題をより早く解決し続けられる土台を作ることにも積極的に投資を進めております。まだまだまだまだ本当に課題ばかりではありますが、変化を一歩一歩、時には飛躍的に起こしていければと考えておりますので、「私ならもっとこうできるよ」「私もJoinしたい」「興味はないけど話くらいはいいよ」などどんな目的でも大歓迎ですので、ぜひお話する機会をいただければと思います。Spirのプロダクトがよりアウトカムを生み続けるために力を貸してください!お待ちしております!

諸々これまで参考にしてきた記事値など

他の記事

NameDate
February 18, 2024 7:24 PM (GMT+9)
February 14, 2024 3:23 PM (GMT+9)
February 13, 2024 11:00 AM (GMT+9)
February 13, 2024 12:05 AM (GMT+9)
February 12, 2024 10:00 PM (GMT+9)
February 10, 2024 11:19 AM (GMT+9)
February 8, 2024 4:42 PM (GMT+9)
February 5, 2024 1:39 PM (GMT+9)
February 2, 2024 2:25 PM (GMT+9)
February 2, 2024 2:25 PM (GMT+9)
February 1, 2024 8:01 PM (GMT+9)
February 1, 2024 6:40 PM (GMT+9)
February 1, 2024 3:44 PM (GMT+9)
February 1, 2024 2:47 PM (GMT+9)
January 31, 2024 9:00 AM (GMT+9)
January 29, 2024 12:19 AM (GMT+9)
January 26, 2024 2:20 PM (GMT+9)
January 25, 2024 2:25 PM (GMT+9)
January 25, 2024 1:08 PM (GMT+9)
January 21, 2024 1:34 AM (GMT+9)
January 21, 2024 12:43 AM (GMT+9)
January 21, 2024 12:35 AM (GMT+9)
January 21, 2024 12:16 AM (GMT+9)
January 21, 2024 12:06 AM (GMT+9)
January 21, 2024 12:00 AM (GMT+9)
January 20, 2024 11:55 PM (GMT+9)
January 20, 2024 11:51 PM (GMT+9)
January 20, 2024 1:07 PM (GMT+9)
January 20, 2024 11:46 AM (GMT+9)
January 20, 2024 12:12 AM (GMT+9)
January 19, 2024 9:34 PM (GMT+9)
January 16, 2024 12:30 PM (GMT+9)
January 15, 2024 2:26 PM (GMT+9)
January 14, 2024 1:16 PM (GMT+9)
January 12, 2024 11:43 PM (GMT+9)
January 12, 2024 8:31 PM (GMT+9)
January 12, 2024 5:27 PM (GMT+9)
January 12, 2024 11:42 AM (GMT+9)
January 11, 2024 9:22 PM (GMT+9)
January 11, 2024 9:14 PM (GMT+9)
January 11, 2024 2:00 PM (GMT+9)
January 11, 2024 1:59 PM (GMT+9)
January 11, 2024 1:43 PM (GMT+9)
January 11, 2024 1:31 PM (GMT+9)
January 11, 2024 1:12 PM (GMT+9)
January 11, 2024 1:09 PM (GMT+9)
January 11, 2024 11:35 AM (GMT+9)
January 11, 2024 11:04 AM (GMT+9)
January 10, 2024 9:11 PM (GMT+9)
January 10, 2024 9:07 PM (GMT+9)
January 10, 2024 8:48 PM (GMT+9)
January 10, 2024 8:38 PM (GMT+9)
January 10, 2024 4:37 PM (GMT+9)
January 10, 2024 3:29 PM (GMT+9)
January 10, 2024 11:41 AM (GMT+9)
January 10, 2024 11:29 AM (GMT+9)
January 9, 2024 10:00 PM (GMT+9)
January 9, 2024 7:10 PM (GMT+9)
January 9, 2024 11:16 AM (GMT+9)
January 9, 2024 9:38 AM (GMT+9)
January 8, 2024 11:23 PM (GMT+9)
January 8, 2024 11:21 PM (GMT+9)
January 8, 2024 10:37 PM (GMT+9)
January 8, 2024 9:46 PM (GMT+9)
January 7, 2024 9:14 PM (GMT+9)
January 7, 2024 9:01 PM (GMT+9)
January 7, 2024 8:53 PM (GMT+9)
January 7, 2024 7:50 PM (GMT+9)
January 7, 2024 6:34 PM (GMT+9)
January 7, 2024 5:35 PM (GMT+9)
January 7, 2024 5:35 PM (GMT+9)
January 7, 2024 5:35 PM (GMT+9)
January 7, 2024 5:35 PM (GMT+9)
January 7, 2024 5:34 PM (GMT+9)
January 7, 2024 5:34 PM (GMT+9)
January 7, 2024 5:34 PM (GMT+9)
January 7, 2024 5:34 PM (GMT+9)
January 7, 2024 5:33 PM (GMT+9)
January 7, 2024 5:33 PM (GMT+9)
January 7, 2024 5:33 PM (GMT+9)
January 7, 2024 5:32 PM (GMT+9)
January 7, 2024 5:32 PM (GMT+9)
January 7, 2024 5:32 PM (GMT+9)
January 7, 2024 5:31 PM (GMT+9)
January 7, 2024 5:31 PM (GMT+9)
January 7, 2024 5:30 PM (GMT+9)
January 7, 2024 5:30 PM (GMT+9)
January 1, 2024 1:45 PM (GMT+9)
December 31, 2023 10:11 PM (GMT+9)
December 31, 2023 10:00 PM (GMT+9)
December 31, 2023 8:12 PM (GMT+9)
December 31, 2023 1:04 AM (GMT+9)
December 31, 2023 1:03 AM (GMT+9)
December 31, 2023 1:02 AM (GMT+9)
December 31, 2023 1:01 AM (GMT+9)
December 31, 2023 1:00 AM (GMT+9)
December 31, 2023 12:59 AM (GMT+9)
December 31, 2023 12:59 AM (GMT+9)
December 31, 2023 12:58 AM (GMT+9)
December 31, 2023 12:56 AM (GMT+9)
December 31, 2023 12:56 AM (GMT+9)
December 30, 2023 11:25 PM (GMT+9)
December 30, 2023 8:37 PM (GMT+9)
December 30, 2023 8:09 PM (GMT+9)
December 30, 2023 7:28 PM (GMT+9)
December 30, 2023 4:32 PM (GMT+9)
December 30, 2023 11:02 AM (GMT+9)
December 29, 2023 11:35 PM (GMT+9)
December 29, 2023 5:58 PM (GMT+9)
December 28, 2023 3:45 PM (GMT+9)
December 28, 2023 1:46 PM (GMT+9)
December 28, 2023 12:32 PM (GMT+9)
December 28, 2023 11:47 AM (GMT+9)
December 27, 2023 12:25 PM (GMT+9)
December 27, 2023 9:28 AM (GMT+9)
December 26, 2023 2:22 PM (GMT+9)
December 26, 2023 11:43 AM (GMT+9)
December 26, 2023 11:40 AM (GMT+9)
December 26, 2023 11:37 AM (GMT+9)
December 26, 2023 11:02 AM (GMT+9)
December 26, 2023 10:35 AM (GMT+9)
December 26, 2023 1:15 AM (GMT+9)
December 25, 2023 11:51 PM (GMT+9)
December 25, 2023 11:50 PM (GMT+9)
December 25, 2023 11:47 PM (GMT+9)
December 25, 2023 11:47 PM (GMT+9)
December 25, 2023 11:44 PM (GMT+9)
December 25, 2023 2:42 PM (GMT+9)
December 25, 2023 12:17 PM (GMT+9)
December 25, 2023 12:16 PM (GMT+9)
December 25, 2023 9:50 AM (GMT+9)
December 25, 2023 9:49 AM (GMT+9)
December 25, 2023 9:48 AM (GMT+9)
December 25, 2023 9:48 AM (GMT+9)
December 25, 2023 9:48 AM (GMT+9)
December 25, 2023 9:47 AM (GMT+9)
December 24, 2023 11:11 AM (GMT+9)
December 24, 2023 2:57 AM (GMT+9)
December 24, 2023 2:42 AM (GMT+9)
December 24, 2023 2:38 AM (GMT+9)
December 24, 2023 2:05 AM (GMT+9)
December 24, 2023 1:59 AM (GMT+9)
December 24, 2023 1:38 AM (GMT+9)
December 24, 2023 1:33 AM (GMT+9)
December 24, 2023 1:21 AM (GMT+9)
December 23, 2023 12:23 AM (GMT+9)
December 23, 2023 12:21 AM (GMT+9)
December 22, 2023 8:00 PM (GMT+9)
December 22, 2023 7:38 PM (GMT+9)
December 21, 2023 5:04 PM (GMT+9)
December 21, 2023 10:22 AM (GMT+9)
December 21, 2023 10:21 AM (GMT+9)
December 20, 2023 4:42 PM (GMT+9)
December 20, 2023 4:41 PM (GMT+9)
December 20, 2023 4:39 PM (GMT+9)
December 19, 2023 6:26 PM (GMT+9)
December 19, 2023 6:17 PM (GMT+9)
December 19, 2023 6:11 PM (GMT+9)
December 18, 2023 4:49 PM (GMT+9)
December 18, 2023 12:50 PM (GMT+9)
December 17, 2023 12:09 AM (GMT+9)
December 16, 2023 10:08 PM (GMT+9)
December 16, 2023 9:22 PM (GMT+9)
December 16, 2023 8:32 PM (GMT+9)
December 16, 2023 8:28 PM (GMT+9)
December 15, 2023 6:32 PM (GMT+9)
December 15, 2023 4:16 PM (GMT+9)
December 15, 2023 3:39 PM (GMT+9)
December 15, 2023 10:18 AM (GMT+9)
December 15, 2023 12:08 AM (GMT+9)
December 14, 2023 9:23 PM (GMT+9)
December 14, 2023 10:39 AM (GMT+9)
December 14, 2023 10:38 AM (GMT+9)
December 14, 2023 10:13 AM (GMT+9)
December 14, 2023 9:57 AM (GMT+9)
December 13, 2023 5:59 PM (GMT+9)
December 13, 2023 5:58 PM (GMT+9)
December 13, 2023 5:56 PM (GMT+9)
December 13, 2023 5:55 PM (GMT+9)
December 13, 2023 5:47 PM (GMT+9)
December 13, 2023 9:53 AM (GMT+9)
December 12, 2023 5:59 PM (GMT+9)
December 12, 2023 5:42 PM (GMT+9)
December 12, 2023 5:01 PM (GMT+9)
December 12, 2023 4:51 PM (GMT+9)
December 12, 2023 9:58 AM (GMT+9)
December 11, 2023 7:53 PM (GMT+9)
December 11, 2023 7:41 PM (GMT+9)
December 11, 2023 5:47 PM (GMT+9)
December 11, 2023 2:13 PM (GMT+9)
December 11, 2023 1:12 PM (GMT+9)
December 11, 2023 10:45 AM (GMT+9)
December 9, 2023 10:44 PM (GMT+9)
December 9, 2023 10:29 PM (GMT+9)
December 9, 2023 2:48 PM (GMT+9)
December 9, 2023 2:44 PM (GMT+9)
December 9, 2023 2:42 PM (GMT+9)
December 9, 2023 2:40 PM (GMT+9)
December 9, 2023 2:39 PM (GMT+9)
December 8, 2023 10:07 PM (GMT+9)
December 8, 2023 7:57 PM (GMT+9)
December 7, 2023 12:14 AM (GMT+9)
December 6, 2023 4:00 PM (GMT+9)
December 6, 2023 12:20 PM (GMT+9)
December 6, 2023 11:31 AM (GMT+9)
December 6, 2023 10:25 AM (GMT+9)
December 6, 2023 10:25 AM (GMT+9)
December 6, 2023 10:24 AM (GMT+9)
December 5, 2023 1:22 PM (GMT+9)
December 5, 2023 12:03 PM (GMT+9)
December 5, 2023 11:50 AM (GMT+9)
December 4, 2023 3:39 PM (GMT+9)
December 4, 2023 11:13 AM (GMT+9)
December 4, 2023 11:10 AM (GMT+9)
December 2, 2023 10:37 PM (GMT+9)
December 2, 2023 10:35 PM (GMT+9)
December 2, 2023 10:20 PM (GMT+9)
December 2, 2023 10:19 PM (GMT+9)
December 2, 2023 3:38 PM (GMT+9)
December 1, 2023 5:46 PM (GMT+9)
December 1, 2023 5:07 PM (GMT+9)
December 1, 2023 1:37 PM (GMT+9)
December 1, 2023 12:15 AM (GMT+9)
November 30, 2023 1:56 PM (GMT+9)
November 30, 2023 1:54 PM (GMT+9)
November 30, 2023 1:53 PM (GMT+9)
November 30, 2023 1:52 PM (GMT+9)
November 30, 2023 1:51 PM (GMT+9)
November 30, 2023 1:47 PM (GMT+9)
November 30, 2023 1:46 PM (GMT+9)
November 30, 2023 1:45 PM (GMT+9)
November 30, 2023 12:36 PM (GMT+9)
November 28, 2023 10:36 PM (GMT+9)
November 28, 2023 10:34 PM (GMT+9)
November 28, 2023 10:29 PM (GMT+9)
November 28, 2023 10:28 PM (GMT+9)
November 28, 2023 10:25 PM (GMT+9)
November 28, 2023 10:23 PM (GMT+9)
November 28, 2023 10:16 PM (GMT+9)
November 28, 2023 10:01 PM (GMT+9)
November 28, 2023 9:54 PM (GMT+9)
November 28, 2023 8:52 PM (GMT+9)
November 28, 2023 8:46 PM (GMT+9)
November 28, 2023 4:46 PM (GMT+9)
November 27, 2023 10:38 AM (GMT+9)
November 27, 2023 1:57 AM (GMT+9)
November 27, 2023 12:42 AM (GMT+9)
November 26, 2023 8:34 PM (GMT+9)
November 26, 2023 3:57 PM (GMT+9)
November 25, 2023 11:41 PM (GMT+9)
November 24, 2023 10:10 PM (GMT+9)
November 24, 2023 3:19 PM (GMT+9)
November 24, 2023 11:55 AM (GMT+9)
November 24, 2023 11:55 AM (GMT+9)
November 24, 2023 1:45 AM (GMT+9)
November 24, 2023 1:43 AM (GMT+9)
November 23, 2023 10:22 PM (GMT+9)
November 23, 2023 6:37 PM (GMT+9)
November 21, 2023 8:22 PM (GMT+9)
November 21, 2023 12:35 PM (GMT+9)
November 21, 2023 11:23 AM (GMT+9)
November 21, 2023 10:35 AM (GMT+9)
November 17, 2023 12:52 PM (GMT+9)
November 16, 2023 12:11 AM (GMT+9)
November 15, 2023 8:44 PM (GMT+9)
November 14, 2023 8:16 PM (GMT+9)
November 14, 2023 6:57 PM (GMT+9)
November 14, 2023 5:18 PM (GMT+9)
November 14, 2023 3:02 PM (GMT+9)
November 14, 2023 11:53 AM (GMT+9)
November 14, 2023 12:14 AM (GMT+9)
November 14, 2023 12:06 AM (GMT+9)
November 13, 2023 11:03 PM (GMT+9)
November 13, 2023 11:02 PM (GMT+9)
November 13, 2023 10:43 PM (GMT+9)
November 13, 2023 12:16 AM (GMT+9)
November 12, 2023 9:53 PM (GMT+9)
November 12, 2023 9:40 PM (GMT+9)
November 12, 2023 8:08 PM (GMT+9)
November 12, 2023 5:42 PM (GMT+9)
November 12, 2023 4:31 PM (GMT+9)
November 12, 2023 4:26 PM (GMT+9)
November 10, 2023 3:53 PM (GMT+9)
November 10, 2023 3:50 PM (GMT+9)
November 9, 2023 10:06 PM (GMT+9)
November 9, 2023 6:48 PM (GMT+9)
November 8, 2023 4:18 PM (GMT+9)
November 8, 2023 1:43 PM (GMT+9)
November 8, 2023 1:37 PM (GMT+9)
November 8, 2023 12:41 PM (GMT+9)
November 8, 2023 12:36 PM (GMT+9)
November 8, 2023 12:26 PM (GMT+9)
November 7, 2023 9:37 PM (GMT+9)
November 7, 2023 9:37 PM (GMT+9)
November 7, 2023 5:28 PM (GMT+9)
November 7, 2023 5:25 PM (GMT+9)
November 7, 2023 2:38 PM (GMT+9)
November 7, 2023 12:12 PM (GMT+9)
November 7, 2023 12:37 AM (GMT+9)
November 6, 2023 11:04 PM (GMT+9)