🤔

「既存プロダクトの引力」をどう断ち切るか? 複数プロダクトを横断するマイクロサービス開発で私が学んだこと

に公開

https://adventar.org/calendars/11579

こんにちは!
マネーフォワード 福岡拠点でサーバーサイドエンジニアをしています、bondeeと申します。

これまで特定のプロダクト(仮にプロダクトAとします)の開発チームにどっぷり浸かっていた私ですが、このたび組織変更があり、 「プロダクトAとB、両方を支える横断的なマイクロサービス」 を作るチームのテックリードになりました。

「新しいサービスの立ち上げだ!マイクロサービスだ!」と意気込んでスタートしたものの、実際に手を動かし始めると、技術的な難易度以上に 「自分の思考のクセ」 との戦いだと気づかされました。

今回は、特定のドメインに強みを持つエンジニアが、横断的なマイクロサービスを設計する際に陥った罠と、そこから学んだマインドセットについて、設計図を交えて振り返ってみようと思います。

「知っている」ことが足かせになる瞬間

今回の一番の難しさは、私が 「元々プロダクトAの人」 だったことです。
プロダクトAの仕様もコードも熟知している。プロダクトBのことも少しは知っている。
一見、これは大きなアドバンテージに見えますが、設計段階では強烈な 「バイアス」 として立ちはだかりました。

脳内構造の可視化:何が起きていたか

設計図を引いていると、どうしても 「プロダクトAではこう動くのが普通だから」 という前提が無意識に入り込んでしまうんです。

気がつくと、汎用的なマイクロサービスを作っているはずなのに、実態は「プロダクトAのための便利機能(ついでにBも使える)」のような歪な構造になりかけていました。

過剰な「わかってる」感の罠

古巣のチームが抱える苦労やUXを知っている分、「あそこを変えるとプロダクト側が大変だから、マイクロサービス側でなんとか吸収してあげよう」 という心理が働いてしまいます。

これは一見「優しさ」のように見えますが、エンジニアリングの観点では 「責務の境界線を曖昧にする行為」 です。

結果として、特定プロダクトの事情に振り回され、サービスの純粋性が失われそうになっていました。

「サービスそのもの」に向き合うマインドセット

この「引力」を断ち切るために必要だったのは、意識的なマインドセットの切り替えでした。

UX要件 vs マイクロサービスの都合

マイクロサービス化すると、モノリス時代には意識しなくてよかった「分散システム特有の課題」に直面します。
例えば、分散トランザクションを実現するための2Phase Commit、SAGAパターンなどの検討や、結果整合性の考慮などです。
各プロダクトのUX担当者は「ユーザーのために(同期的に)即時反映させたい」と考えます。
しかし、それを鵜呑みにしてマイクロサービス側で無理やり整合性を担保しようとすると、システムが複雑化し、パフォーマンスも劣化します。

要件定義の前段階での「調整」

ここでテックリードとして大切だと感じたのは、コードを書く前の 「調整」 です。

「UXのために技術を曲げる」のではなく、「技術的な制約(マイクロサービスとしての正しさ)」を説明し、 「UX側を調整してもらう」 プロセスが不可欠でした。

コンウェイの法則と開放閉鎖の原則(OCP)の再発見

開発を進める中で、教科書で読んだ理論が肌感覚として理解できるようになりました。

「現在の組織図」を設計図にしない

「コンウェイの法則」(システム設計は組織構造を反映する)の本当の意味を痛感しました。

これは特定のプロダクトに肩入れするというよりは、「現在の組織構造(プロダクトAチームとBチームがいる状態)」 を前提に設計が最適化されてしまう怖さです。

「今はAとBしかいないから」といって、その2つのチーム構造にベッタリと依存した設計にしてしまうと、それは 「現在の組織図のスナップショット」をコードに焼き付けることになります。 将来組織が変わったり、新しいプロダクトが増えた瞬間、このアーキテクチャは変更に耐えられず破綻するでしょう。

サービスレベルでの「開放閉鎖の原則 (OCP)」

そこで、変化に強い設計にするために、SOLID原則の 「開放閉鎖の原則(Open/Closed Principle)」 をアーキテクチャ全体に適用する必要性を強く感じました。

単にコードを綺麗にするためではなく、「今の組織構造が変わっても、サービス自体は変更しなくて済む」 ようにするためです。

  • 拡張に対しては開かれている(Open): たとえ組織が変わり「プロダクトC」が生まれても、アダプターを追加するだけで対応できるか?

  • 修正に対しては閉じている(Closed): 個別のプロダクト(組織)の事情が変わっても、コアロジック(Core)は影響を受けずに済むか?

「組織の形」と「システムの形」を切り離し、サービスの独立性を守るためとして、OCPが非常にしっくりきました。

技術選定とドキュメントの大切さ

ここまでの設計原則が「サービスの構造的な独立性」を守るためのものだとしたら、ここからの技術選定やドキュメントの話は 「エンジニアの心理的な独立性(認知負荷の軽減)」 を守るための取り組みです。

複雑な横断システムだからこそ、開発者が迷わずコードに向き合える環境づくりが必要でした。

認知負荷を下げるための「責務範囲」

「どこまでが僕らの責任で、どこからが利用側の責任か」。 これを開発前に徹底的に定義しようとしています。

これは責任逃れのためではなく、エンジニアの認知負荷(Cognitive Load)を下げるためです。 バウンダリが曖昧だと、エンジニアは常に「あっちのシステムの挙動」まで気にしなければなりません。それでは開発速度も品質も上がりません。

「ここから先は僕らの城」と決めることで、チームが集中できる環境を作りたいと考えています。

モチベーションとしての技術選定

技術選定においては、「現在の規模に合っているか」という合理性はもちろんですが、 「エンジニアがワクワクするか」 も無視できない要素だと感じています。

「枯れた技術」は安全ですが、それだけでは開発者のモチベーションは維持できません。 テックリードとして、堅実な設計という土台の上に、メンバーの知的好奇心を刺激するような「挑戦的な技術」をどう組み込むか。

そのバランス調整もまた、組織作りにおいて重要な設計の一部だと思いました。

「意思決定」をドキュメント化する

開発が長引くと、人間どうしてもマンネリ化して「いつもの慣れた技術」に固執したり、逆に「新しい技術を使いたいだけ」になったりします。

だからこそ、ADR (Architecture Decision Records) のような形で、意思決定のプロセスを文書化することが重要だと痛感しました。

  • なぜこの設計にしたのか?
  • なぜあえてこの技術を選ばなかったのか?

これを残しておくことで、未来の自分や新しいメンバーが迷ったときの道しるべになります。ドキュメントは、過去の自分たちからの手紙みたいなものですね。

おわりに

複数サービスを横断する開発は、技術的な挑戦であると同時に、「自分の中にある常識やバイアス」との戦いでもありました。
特定のプロダクトへの愛着や知識は、武器にもなれば足かせにもなります。

そのことを自覚し、適切な距離感を保ちながら「あるべき姿」を追求し続ける。それが、横断組織のエンジニアに求められる一番のスキルなのかもしれません。

もし同じような立場の人がいたら、「一度、古巣のことを忘れてみる」 ことから始めてみるのをおすすめします!

ここまでお読みいただきありがとうございました。ヽ(o'v'o)ノ

Money Forward Developers

Discussion