📝

【備忘録】アーキテクチャConference 2025 で 学びと気づきが得られすぎたので、共有したい...

に公開

はじめに

昨日、一昨日にかけて開催された、アーキテクチャConferenceに参加してきました。

本イベントを通じて、自分自身がまだ足りていないスキルを明確にできたり、今の企業が直面している課題、そしてそれをどのように解決していくかのヒントを得ることができました。
まだ完全に理解できたわけではありませんが、非常に多くのことを学ばせていただきました。

本記事では、カンファレンスで得られた学びを自分自身の備忘録として残すとともに、参加できなかった方々にもその内容を共有したいと思い作成しました。
各セッションから得られた気づきを自分なりにまとめてみましたので、ご覧いただけると嬉しいです。

アーカイブや登壇資料は、下記から確認できます。ぜひチェックしてみてください。
https://conference.findy-code.io/conferences/architecture-con-2025/7/archives/slides

アーキテクチャConference 2025とは

アーキテクチャConference 2025は、ファインディ株式会社が主催する「アーキテクチャを知り、学ぶ2日間」をテーマとした技術カンファレンスです。

ソフトウェアアーキテクチャの最新トレンドや実践事例、マイクロサービスアーキテクチャ、AI駆動開発など、現代のソフトウェア開発における重要なテーマについて、第一線で活躍するエンジニアたちが知見を共有する場として開催されました。

https://architecture-con.findy-tools.io/2025

目次

記事の内容がかなり多くなりました...
興味あるところだけでもご覧いただけると嬉しいです!

  1. アーキテクチャの目的とマイクロサービスの位置づけ
  2. モジュラーモノリス→マイクロサービスの移行パターン
  3. チーム・組織構造とアーキテクチャ
  4. ドメインモデリングと結合度の設計
  5. AI時代の開発プロセスとアーキテクトの役割
  6. AIナレッジベースと情報設計
  7. 変更容易性と設計改善の戦略
  8. レジリエンスと運用(障害に強いシステム設計)

1. アーキテクチャの目的とマイクロサービスの位置づけ

マイクロサービスは手段であり、目的ではない

マイクロサービスにするべきかどうかは、「それによって得られる成果」が明確かどうかで決まります。

  • 「マイクロサービスにしたい」自体を目的にしない
  • Deployの速度が遅くなったなど、マイクロサービスにする必要性を認識した時に、初めて検討する
  • 手段を先行させない

これらを意識することが重要です。

ユーザー視点でのアーキテクチャ選択

ユーザーもビジネスサイドの人も、「マイクロサービスかどうか?」は気にしていません。

つまり与えられる価値によって、マイクロサービスにするかどうかは決めるべき、ということです。
与えられる価値が、マイクロサービスによって増えるなら、マイクロサービスにする、という判断ができます。

なぜマイクロサービスが有効なのか?

アプリケーションの規模は、次第に大きくなっていきます。
それに伴い、デプロイの時間やデグレチェックなどで、変更を反映するまでにかかる時間が増えていきます。

これを回避するためにも、マイクロサービスは有効です。
重要なのは、小さくてかつ頻度の高い変更を実現することになります。

アーキテクチャの本質

アーキテクチャは、「何を使うか?」ではなく、「何がしたいか?そのために何が必要なのか?」を考えることです。

  • 単語ベースだけで話をしない
  • アーキテクチャには、常にトレードオフが存在する
  • 決まりきった結論を出すのではなく、状況に応じて判断する

ソフトウェア開発の目的

ソフトウェアシステムは、事業活動を効率的かつ効果的に進めるための仕組みです。開発して運用する目的は、好業績を担保するためにあります。

2. モジュラーモノリス→マイクロサービスの移行パターン

移行の手順とコツ

モジュラーモノリスから、マイクロサービスに移行する時の手順:

  1. 徐々に移行していく
  2. 新サービスの開発とデプロイを分ける - 作った後にすぐリプレースしない
  3. 旧サービスも残しておく - 新サービスがバグってた時もすぐにロールバックできるようにする
  4. 新しく作ったサービスを測定する - 正しく動作しているか?コストはどれだけか?を測る

初めからマイクロサービスで進めるとうまく行かない

「モジュラーモノリスとしてやってたけど、うまく行かなくなった」というタイミングで、マイクロサービスにするのが適切です。

モジュラーモノリスの実装ポイント

モジュラーモノリスの実装部分は、外部API部分だけ公開して、内部実装は隠すのが重要です。

例えば、Goではinternalディレクトリを作ると、外部からアクセスできなくなります。

モジュラーモノリスの限界

物理的な空間分離の限界

一つ一つの機能単体で、デプロイできない。

時間的分離の限界

同期呼び出しになるので、一つの障害が他に影響する。

位置透過性の重要性

位置透過性があると、モノリスからマイクロサービスへの移行が直ぐにできるようになります。結果的にソースコードの変更を抑えることができます。

3. チーム・組織構造とアーキテクチャ

サービスチームの重要性

開発チームを、サービスチーム(そのチーム内で要件定義〜テストまで行えるチーム)で完結させると、迅速な意思決定と主体性を育めます。

サービスチームのメリット:

  • コミュニケーションコストが低くなる
  • 信頼関係を構築しやすい - なぜそれをやろうとしているのか?背景情報・考えていることを理解できるから、コミュニケーションの摩擦が少なくなる

ここまでみた

  • サービスチームがプロダクトに対するオーナーシップを持つので、主体性も育める

ドメイン型 vs プロジェクト型のチーム体制

ドメイン型のチーム体制

メリット:

  • 持続可能性高いエンジニアリングができる
  • 深い知見が溜まりやすいので、オーナーシップを与えやすくなる

デメリット:

  • ドメイン分割する境界を定義しにくい
  • 非注力なドメインがある場合は、開発チームを継続的に配置するのが難しい。注力対象が変わるスタートアップだと難しい

プロジェクト型のチーム体制

メリット:

  • チーム組成が簡単
  • 開発作業に集中できる

デメリット:

  • 持続可能性が低い
  • 深い知見がたまらない。一年前に作った機能を忘れて、開発効率が遅くなる

プロジェクト型での工夫

もしプロジェクト型にしたとしても、持続可能性について検討しておきましょう。事前に誰が、何をやるか?という所を決めておくと、責任が明確になるのでおすすめです。

フルスタック & フルサイクルの重要性

サービスメンバーが、全員**「フルスタック & フルサイクル」**だとコミュニケーションコストが減ります。

また、職能におけるボトルネックの排除ができます。職能で分けると、何かの職種のタスクでボトルネックになるので、そこを避けることができます。

チームに高度な専門性が必要かどうか?

現在は、クラウドなど「テクノロジーのコモディティ化による恩恵」があります。そのため、ある程度はジェネラリストでも対応できます。

専門性の高い領域は、横断チームとして切り出す:

  • セキュリティチームなどは、別で切り出せばいい
  • 実際は、人にはそれぞれ得意領域があるから面白い
  • そのため、専用の人を雇わなくても、誰かが得意、という状況が起こる

必要に応じて専門職を採用するメリットもあります。専門職の人によって、周りの人たちのレベルを上げることもできるからです。

採用権限の委譲

現場チームに採用の権限を任せるのも有効です:

  • 現場の人が一番どんな人が欲しいかわかってる
  • 募集要項、スカウトメールまで現場の人が考えたりする
  • また、最終的には登壇などによる認知度向上など、活動勝負になるので、オーナーシップを与えることが重要
  • 随時HRの人ともコミュニケーションをとる

規模とオーナーシップのトレードオフ

規模が小さいと、オーナーシップを発揮しやすい反面、知見の共有や技術的なエコシステムの構築は難しくなる

プラットフォームエンジニアリング

プラットフォームエンジニアリングとは、ソフトウェアの開発とデリバリを目的として、セルフサービス型の開発者プラットフォームの構築と運用に関する専門分野のことです。

組織構造の考え方

  • 会社組織としての組織と、価値創出を目的としたチーム
  • 仮想組織として、PMやデザイナーなどの職種のメンバーを全員入れて、それぞれの職能を持った人が集めたもの
  • 対象のサービスでバックエンドが既に作成済みなら、フロントエンドだけのチームも作る

Platform Engineering が作成されるきっかけ

開発チームが全てを担当するのは限界があります。だからこそ、インフラ周りの整備の専門家で切り出したりします。

会社の状況に応じて、専門領域を作るべきか変わる:

  • 小さい会社なら、少人数で全部やる
  • 大きい会社なら、分業していく
  • 中間層として、PFEでオフロードする、が入る。規模が大きくなると分業が進む

Mob Elaboration

エンジニアとビジネスサイドの人が、一緒にぐるぐると開発を回していくスタイルです。全員が仕様を理解した上で、2〜3名の人たちで開発していきます。

組織拡大に伴う課題

組織が大きくなると、互いのチームに確認が必要になり、一旦はDeprecatedでいいや、になり後回しになりがちです。
また組織が拡大していくにつれて、どんどん別の課題が出てきます。

特に課題になりやすいのは...

  • どのチームが、どのAPIを使ってて、みたいなのがわかりにくくなる
  • 要件定義する時に、チーム間でコミュニケーションコストが増える

4. ドメインモデリングと結合度の設計

AIでの開発を進める上で、重要なアーキテクチャ 6選

  • 境界付けられたコンテキスト
  • イベント駆動アーキテクチャ
  • CQRS(Command Query Responsibility Segregation)
  • AVDM(Always-Valid Domain Model)
  • Type First - 型エラーで事前に駆動できる
  • Event Sourcing - なぜそうなったのか?の検査の精度もあげられる

CQRS を取り入れることのメリット

ファイルごとに処理を分けることで、「人がどこに注力するべきなのか?」をチェックできる

レビューした方がいい所は重点的に見つつ、そうじゃない所はテストと型エラーを軽く見るだけで済む。このグラデーションをつけることが重要です。

イベントソーシングの本質

全ての変更を記録することです。これは、ステートソーシング(データの現在の状態だけを保存する)とは異なります。

これがあると、何が起きたか?を流れとしてわかるようになります。

Always Valid Domain Model(AVDM)とは?

常に正しい状態を、インメモリでDBとは関係ない状態で作ることです。

例えば、C#で、Pureなオブジェクトを作る、などです。

結合のバランス

  • 実装や進化、メンテナンスが容易なモジュラーシステムを設計すること
  • 結合の3つの次元全てを考慮すること

結合強度と距離の関係

知識をつなげるのはなにか?(結合強度)

1. Instrusive Coupling(侵入的結合)

内部な詳細実装を知るのは罰。Privateで、結合用じゃない実装も知っていると、それによって片方が変更されても、依存してるのが気づけない。ここが暗黙的で、注意しないとダメだから、非推奨

2. Functional Coupling(機能的結合)

機能単位で結合している。同時に両方に変更が行うようになるので、機能が分割されると、同時に両方修正が必要になる。

3. Model Coupling(モデル結合)

同じビジネスモデルを使ったもの。上流のモデルを変更する時に、他への影響は考え合わないとダメ。

4. Contract Coupling(契約結合)

非結合で、安定してる。契約の結合で、カプセル化されてて共有しないといけない情報量が一番小さい。

距離と変更の難易度

距離があればあるだけ、変更するときの影響が大きくなる

  • マイクロサービスの場合、変更するのが難しい
  • 変更の同期が難しい、別チームで対応しているなど、組織のあり方でも変わってくる
  • 距離が近ければ、そこまで変更は難しくない
  • 結びつきが大きいモデル同士でも、距離が近ければ変更できる
  • 逆に距離が遠くと難しい、さらに強い結びつきであれば尚更大変になる

モジュール性は、結合強度と距離によって決まる。ここの結合強度は、ビジネスサイドに影響されます。

サブドメインとは?

一緒に変更を加えるような、ビジネスロジックを人まとまりにしたものです。

サブドメインの3種類

Core(コア)

競合優位性で、経験則とか複雑さを伴う領域。Coreサブドメインに関しては、一番成長を続けていく必要がある

Generic(汎用)

すでに解決されているモデルで、コスト削減の効果が高いため、SaaS等を利用して時間を節約できる。

Supporting(支援)

コアとジェネリックの中間で、競争優位性もないけど、内製したもの。

重要なところを理解して、それ以外の重要じゃない所は、コストをかけすぎないことが重要です。

サブドメインと境界付けられたコンテキストの関係性

1:1が理想ではあります。分ける目安としては「保持すべきデータ・属性がコンテキスト内にあるか?」で分けます。また、技術と組織での分け方もあります。

いつ分けるべきか?

サブドメインで分ける時、業務ごとに組織を分けることが多いから、その単位で分けます。具体例としては、会話する相手が変わったりした時、などです。

ビジネスとシステムの関係

ビジネスとシステムがズレる場合があります。つまり、システムはビジネスの変更を追い続けるしかない

イベントストーミングで、コンテキストマップを使いつつ、AS-ISを書きながら、ToBeで夢を見る、というアプローチが多いです。

サービスを分けたくなる瞬間

パフォーマンスが求められるようになった時です。

全部一気にサーバーの質を上げると無駄になるから、一部分だけパフォーマンスを上げるための仕組みを作るなどです。ここだけで切り出せれば、無駄を減らせます。

境界分割後の実装順序

コアドメインをメインでやる。ビジネス上での優位性になるため。その後に、サブドメインにするのがいいと思います。

タスク着手の優先順位は、プロジェクトの状況によっても変わります:

  • 新しい新規機能に関しては、一番難しいのから解決するといい
  • 既存実装に関しては、依存関係がないものからやる
  • その上で、処理の流れから見た時に「最後か最初」の処理から対応する

依存関係が少ない所から実装できると、スムーズにいきます。

DDD はどれに適用するべきか?

コアドメインに関してはDDDでいいけど、それ以外で不要なサービスは無理してDDDしなくていい

エンジニアは、バリューを出すことを意識する必要があります:

  • バリュー出さない限り、何も意味ないじゃんって言われないようにする
  • それに応えるのは、エンジニアの説明責任にもなる
  • だからこそ、コアドメインに注力するべき

5. AI時代の開発プロセスとアーキテクトの役割

AI と人間の役割分担

AIはいづれ人間を凌駕する、それは段階的に起こりうります。最終的には責任を負って、信頼を勝ち取ることが人間の役割になります。

  • AIは、責任を果たすことが難しい
  • 人間はAIを信頼し切れるのか?という疑問が残るので、人間がここを保証する必要が出てくる
  • 具体的には、最後の検査等を人が行い、責任と信頼を持つのが大切

人に求められる責任の増大

今後、人に求められる責任の量が多くなるのではないか?

  • 求められる責任の量が増える
  • 求められる責任の水準も上がる
  • 非エンジニアのリテラシーが向上して、定量的な信頼性と適切な説明責任が出てくる

エンジニアの検査方法

今後エンジニアは、AIの成果物に対してどう検査していくべきか?今後は、専門的な知見をもとにした説明が必要になります。

以下の軸で、検査を進める必要があります:

  • 判断の基準(客観 ↔ 主観)
  • タイミング(予防 ↔ 回復)

アーキテクチャによる認知負荷の軽減

アーキテクチャは、認知負荷を軽減する鍵になります。
上手くアーキテクチャを構築すると、人がレビューするときの負荷を減らせます。

ユーザー視点を徹底する

サービス設計時、「その機能が必要な理由」をなぜなぜと繰り返して問いかけて理解します。

それにより:

  • お客さんのことを理解できるようになる
  • ユーザーの真のニーズが見えてきて、製品にもそれが反映される
  • ユーザーの課題を解決することで自信がつくようにもなる
  • 必要に応じてセールスとも会話して、今顧客が何を求めてるか?も随時把握する

Figmaのアーキテクチャ選定基準

パフォーマンスを最重要に考えている。

  • フレームレートは、1秒あたり60コマから30コマにならないか?などを重点的にテストする
  • ここの最重要事項、ケアするべきとこは、集中して確認する

アプリケーションのパフォーマンスは、エンジニアリングの問題だけではありません。デザインが問題になる可能性もあります。

AIによる役割の変化

AIによって役割が変わったとしても、常に「ユーザーが何を求めてるか?を徹底して考える」ことが重要です。

  • エンジニアであれば、実現可能性の観点から見る
  • 肩書きではなくて、何をやるか?が重要になる
  • どうしてこれをやるか、なぜそれの優先順位が高いのか
  • 製品の整合性などで、Why Howを出しつつ、人間的な所から、ベストな経験はなにか?を考える

アイデアの創出方法

アイデアは、面白い、ワクワクするようなストーリーから逆算して作る。そこからのストーリーを作らないと、意義が少なくなる可能性が出てくる。
ナラティブから始めて、実際の付加価値をつけていきます。

新しい機能を作り出すなら、まずは何を考えるべきか?

最初に頭に浮かぶ時は、最初はスタンダードな、なぜそれをやるのか?そして、どうして面白いのか?なぜそれがワクワクするのか?

ユーザーが見た時に、「それは価値がある」って分かるならいいアイデア。逆にすぐ理解できなかったら、何か間違えている可能性があります。

AI活用のポイント

AIに色々なタスクを任せると上手く動かない場合があります。
必要に応じて、AWS Resource Explorerを使うなど、必要なリソースをわかりやすい形でアクセスさせるのが大切です。
これをSQLiteでインデックス化すると、より高速にアクセス可能にもなります。

Devin を使うメリット

雑に聞いても、複数のレポジトリを横断して調べてくれます。つまり、一メンバーとして動いてくれるし、プロンプトで正しい情報を与えなくても、いい感じで回答してくれるのはかなり役立ちます。

AIの本質的な3つの力

  • 幅広い知識の補完
  • 文章・コード・情報の整理
  • 人間の得意なことを支えて、面倒なことをやってくれる

90%の簡単なコードを書くことには価値がなくなった、でもどんなコードを書くべきか、のアーキテクトの重要性は1000倍になった。

AIは知識の代替ではなく、能力の増幅機

  • 使い手の能力がないとダメ
  • AIを能力向上のために使う必要がある
  • 結局、自分自身のスキルアップが大切

AIコーディングの価値はスピードだけど、一方で品質が落ちる可能性があります。結局人がレビューする必要があります。

またアーキテクチャはコンパスで、完璧な地図は書けません。
あくまで方針を示しているだけです。

AI時代での開発者の役割

  • アーキテクチャの方針を決定
  • ドメインの本質を理解
  • 制約とガードレールを定義

AI-DLC(AI Development Life Cycle)

大きく三つあります:

  • Inception - 開始
  • Construction - 構築
  • Operation - 運用

AI活用の実践方法

AIが出してきたコードをいきなり読まず、まずは実装計画を作る

これにより、レビュー負荷を大幅に下げられる

複雑なタスクを生成AIに依頼する時

「自分なりにタスクを分解した」上で、それらの流れをAIに伝えると上手くいく

AIが意図してない動きをした時は、修正や調整を行う

意図せずに実装されたりする場合には理由があります。そこで明確な指示とかコンテキストを調整するのが大切です。

AIが理解しやすいコードベースが必要

AIが間違えないように型とかプロップス名を修正するといい。

AIが書くソースコードで担保せず、決定的なミドルウェアで防げないか?を考える

これで防げると、AIの実装からの不安を避けられます。プログラムに頼らない設計が大切です。

AI浸透の方法

  • 技術の組織トップが、AIでコードを書きまくるのが大事
  • ゴール設定も大切、いつまでに、誰か、どのレベルまで到達するか?
  • チームごとにAI Champion(AI 精通者)を置く - チームごとに触ってる領域は違うからこそ、全体を底上げする
  • AI Native Day(AI だけ使って業務する日)が重要 - ハッカソンだけでなく、通常業務でも行わせる

ゼロから技術選定する時の考え方

  • ナレッジ(暗黙知の防止)が大切になる
  • 時間が変わると、新しい書き方に変わるので、それを追えるようになる

これをすると、AIが自分で間違いに気づけるようになります。

新しく触る技術の学習方法

新しく触る技術では、「腹落ちするまで、AIと対話する」のが大切です。
AIに壁打ちできるので、初めて触る技術を選択しやすくなってます。
また、一番初めのところは、自分で作れると良さそう。

コード品質の維持

コード規約の重要性

人間には、多すぎるくらいのコード規約を使った方が、後々で楽になります。
ES-Lintによって、AIの出力を安定できます。

定期的なリファクタリング

AI任せに実装してたら、コードがぐちゃぐちゃします。
2週間に一回くらいは、リファクタリングをするのが大切になります。

しっくりこなかったら

AIと壁打ちして考え直して、AIに一気に修正させる。
どんどん設計をブラッシュアップしていくのが大切です。

6. AIナレッジベースと情報設計

人間が補足情報を加える重要性

ソースコードのリバースエンジニアリングだけだと、「なぜそれをしたのか?」の文脈が失われがちです。

なので、わからないこと・決まってないことを人が決めた上で、再度AIに考えさせるのが大切です。

  • AIに推論させず、人間が必要な背景情報は人が与える
  • この時に、「まだ決まってなかった、必要な仕様を認識」できる
  • ドキュメントの質向上に加えて、足りてない項目は補足できる

AI リーダブルな情報設計

情報は、AIが収集・生成・提案して、人が判断するようになります。
AIが読める情報を増やしていく、AIリーダブルな情報設計が必要です。

情報負債が起こる原因

情報負債が起こる原因は大きく3つ:

  • 分散
  • 形骸化
  • 属人化

なぜ情報が分散するのか?

  • ドキュメントの責任範囲が曖昧
  • 検索性・再利用性よりスピードを優先
  • 情報構造の設計思想が存在しない

AIナレッジベースによる情報の一元化

  • 事業運営に必要な情報を一元管理
  • 人が必要な根拠・文脈に辿り着けるようにする
  • 人とAIが同じ情報で判断できるようにする

形骸化する原因

  • ドキュメントが利用できず、古いまま放置されてる
  • チームの運用手順書が古いので、手戻りが発生
  • 結果的に、AIが間違った分析をしてしまう

なぜドキュメントが形骸化するのか?

  • 頻繁な仕様変更に追従が大変
  • 古くても誰も困らず、責任が曖昧
  • 成果に直結しにくい

保守が後回しになりやすい構造になります。

ドキュメント運用の自動化

Docs-as-Codeでドキュメント運用の自動化をするといいです:

  • CIで常に更新させる
  • Cronで定期的に情報収集させる
  • 必要な加工をした上で、ナレッジの情報収集を行えるようにする

属人化の問題

なぜ情報が属人化するのか?

暗黙知による属人化が起こります:

  • 知見が個人に依存してる
  • 「あの人しか知らない」を放置しても、問題化されない
  • 誰がどの知識を持っているかが分からない

属人化の対策方法

  • AI前提の業務プロセス設計を構築する
  • ドキュメントが自動的に生まれる仕組みを作る
  • 会議 → 自動要約 → ナレッジに自動追加

AIナレッジベースの情報設計

  • GitHubレポジトリを採用
  • レビューや自動化を容易に
  • Markdownを利用する
  • AIの挙動を制御するガードレールを整備する、など

ドメイン知識の活用

ドメイン知識をナレッジベースで貯めておくと、意図に沿ったクエリを出せたり、結果を出力できます。その結果、設計の壁打ちでも使えるようになるかもしれません。

定期的なAI実行

定期的にAIに動かして、ドキュメントを常に更新します:

  • 情報 × 状態 = 次のアクションを決める
  • 推論させる時と、機械的に動かす、をきちんと分ける
  • 業務推進の自動化がどこまでできるのか?が重要になる

暗黙知とナレッジ管理

AIがうまく動かない理由の一つに、暗黙知があります
暗黙知に関しては、AIは理解できません。

以下の流れが重要:

  1. AIにコードを書かせる
  2. おかしな参照・設計が出たら、CLAUDE.mdを随時修正していく

ナレッジ貯めて、コード書かせて、うまく行かなかったら、それを修正させる。

ナレッジ自体をAIに書かせる

期待通りじゃなかったら、CLAUDEに「何が書いてあればよかった?」をAIに考えさせて改善します。

今後のバグ対策もAIを活用

インシデントなどの履歴とかPRをAIに渡して、それを防ぐにはどうしたらいいか?を考えさせて、追加します。
これを元に、リスク評価を自動化するのもできます

7. 変更容易性と設計改善の戦略

今までとこれまでのソフトウェアに求められる要件

今までは、データのCRUDと単純な加工で重宝されていたけど、今は状況判断・推論・決定をソフトウェアシステムに組み込む必要があります。

また、事業活動と広く深く連動するソフトウェアは複雑であり、変化を繰り返すし、未知の課題に不確実な状況で取り組む必要があります。

一方で時間と資源は限られてます。トレードオフが大切です。

いい設計を生み出す基本原則

  • 変更容易性に焦点を合わせる
  • 事業活動を理解して、設計判断する

設計とは何か?

ある目的のために、形のないところに形を与え、その形を変え続ける活動です。

また、良い設計は悪い設計よりも変更しやすい

より実践的なソフトウェア設計の本質

整理整頓されたコードは、乱雑なコードよりも変更が楽で安全である。

いくらドキュメントがあっても、コードが汚いと変更しにくくて、事業に損失をもたらす可能性があります。

事業活動を理解して、設計を判断する

設計改善(整理整頓)に使える時間は限られてます。普段の開発や障害対応をしつつ、設計改善するのは難しいです。

だからこそ、ソフトウェアシステム全体の**「どこを、いつ、どこまで」整理整頓するか?**

必要なところを、事業戦略と紐づけて考えるのが重要です。ここでも、トレードオフを意識する必要があります。

差別化戦略とソフトウェア設計

どこを、いつ、どう変更するか?は、事業戦略と、自分達はどこに強みがあるか?を合わせる

差別化戦略に適合する、ソフトウェアの設計方針の開発の優先順位を見つける。逆に、差別化に寄与しないところは、そこまで修正しなくて良いです。

差別化にかなり寄与していて、その上で業務ロジックも複雑であれば、そこは中核の業務領域になります。ここは、継続的に重点的に取り組めると良いです。

設計改善の費用対効果を最大にする

  • 小さな設計改善を開発組織全体で継続する
  • 戦略的に重要な箇所を「重点的」に設計改善する

広く、薄く、ちょっとずつ進めていくのが大切。同時に、やらない所をどうやって選ぶか?が重要になります。

実践的で効果的なアプローチ

  • 機能修正や機能追加の重要度を、事業視点で判断する
  • 重要な機能修正や機能追加の「対象範囲に限定」して、乱雑なコードを整理整頓する
  • 乱雑なカードを整理整頓することで、変更が楽で安全になった効果を検証する。綺麗になった、以上ってだけに終わらせず、機能追加が安定したという結果を検証する

ソフトウェア設計のアンチパターン

  • 初期の設計に時間をかける
  • 事業的に重要度が低い場所の設計改善に時間をかける
  • 乱雑なコードを整理整頓しないで、機能を修正追加する
  • 機能の修正追加が不要な箇所を整理整頓する

たとえ短い時間だったとしても、コードを綺麗にすると、機能追加もすぐできるようになります。

また、重要なのは「何をやらないか?」です。

設計改善(コードの整理整頓)三つのレベル

  • 小さな設計改善
  • 大きな設計改善
  • 戦略的な設計改善

これらは、並行して進める必要があります。下に行けば行くだけ時間がかかるし判断しにくいけど、進めていく必要があります。

小さな設計改善

  • 不要なコードを削除する
  • チャンキング(異なる関心事の境界を見つける)
  • グループ分けした単位に名前をつける

中級レベル

関連するロジックとデータを一つのクラスに集める。クラス名とメソッド名で意図を説明する:

  • 算術演算 / 比較演算 / 論理演算のカプセル化
  • コレクション操作のカプセル化
  • 区分を使った条件分岐のカプセル化

一旦カプセル化した上で、さらにそれを分割するような形になります。

大きな設計改善

  • 計算判断・出力・入力の三つの関心事を、クラスとパッケージを使って切り離す
  • アプリケーション特化のデータ型(値オブジェクト、コレクションオブジェクト、区分オブジェクト)を使って、計算判断ロジックを書く

戦略的な設計改善(戦略的なコード整理)

事業戦略とソフトウェアの実装を結びつける。

差別化戦略、競合他社と異なる、自社独自の価値提案がある。その上で、ビジネスルールがあり、差別化戦略の実行手段が決まっていく(適切な行動を刺激・不適切な行動を制限)。

これが、差別化戦略を具体的にしていきます。その上でこのビジネスロジックに基づいて、計算判断ロジックを作ると、事業戦略がコードに紐づく

コードの複雑性は2種類ある

Essential Complexity(本質的複雑性)

  • ドメインに固有、除去不可能

Accidental Complexity(偶有的複雑性)

  • 技術的制約、フレームワークで削減可能

偶有的複雑性をどれだけ削減できるか?が重要です。

データベースによる制約に縛られないため、インメモリの中で解決できるようにする。
モデル全体や設計を、データベースとは異なる方法で構造化する。初めは大変だけど、後々楽になっていきます。

後悔しないアーキテクチャ

後悔しないアーキテクチャを作るために、最初からスケールアウト出来る設計で作っておく

  • 後々で、DBがボトルネックになる
  • 最初からやっておけばよかった、を防げる

まずは小規模でスタートして、徐々にスケールさせる

  • ある程度コストを前払いする必要がある
  • 学習コスト、初期設計、フレームワーク選定も重要
  • これにより、後々からの後悔を避けることができる

判断基準としては、将来のリアーキテクチャコストがどれだけかかるか?後でリアーキテクトするなら、作る前から意識できると良さそうです。

設計は選択肢を知っておくことが重要

  • 詳しく知らなくても、コンセプトを理解していると、AIのアシストで採用していくことができる
  • また、完璧ではなく、「選択に納得できる」ことをすることが重要

アーキテクチャ判断の実践

砂時計というアンチパターン

理想と期待値は多いのに、肝心のロジック部分の話があまり出来ていない場合があります。バズワードを使うと注目は集められるが、中身の内容こそ肝心です。

大企業のアーキテクチャを真似するだけではダメ

Googleのアーキテクチャが、自分たちの会社に最適ではない。自分達の要件にあったものを考える必要があります。

時には、一歩下がって見るのも大切

  • どういう前提を自分で考えるか?を認識する
  • アーキテクチャする時は、AIを使って壁打ちをする

アーキテクチャを検討する時は、「実際のデータ・数字」を把握して考える

  • 3倍のコストでも、$10 Vs $30か、$10000 vs $30000で変わる
  • スケールはどれくらい欲しいのか?どれくらいのトラフィックがあるのか?にもよる

判断するためには、リアルなデータが必要になります。

常に他の選択肢があるかも、見落としていることはあるかも?と考える

  • 実際はもっと選択肢があるのではないか?をアーキテクチャは考える
  • 問題を一視点しか見てないと、解決できない
  • 何か勘違いしている可能性がある、という前提も持つ
  • そもそも今適切な情報になってるのか?
  • 今のトレードオフは何なのか?
  • 途中にある意思決定が重要になる
  • いろんな可能性が無限に出てくる、ここの途中の過程があるから面白い

モノリス、マイクロサービスではなく、4つの領域で考える

  • Replicas
  • Modular Monolith

の二つが存在します。問題は何か?を理解した上で、何が必要なのか?を考える必要があります。

変化に対する考え方

変化するのにも、いろいろな背景があります:

  • どうしてこのバージョンを延長させるのか?
  • 変更するコストもかかる
  • だからベンダーロックインが起こる
  • でも、これは必ずしも悪いことではない
  • 一度いろいろな次元を理解すると、よりよい意思決定ができるようになる

常に「一番インパクトが大きい所」を考える

  • レイテンシーであれば、一番のボトルネックを解消する必要がある
  • また、重要な要件を明確にして、一貫性を持つのも大切
  • いろいろと最適化しようとして、複雑になりすぎるとマイナスに

いい設計には、「トレードオフ」が付きまとう

  • ちょっとしたトレードオフ・衝突が存在する
  • 早く価値は出したいけど、一直線で行かない時もある
  • その時には、常に重要な原則に則って判断する

早々と意思決定をしきらない

  • プロジェクト初期が、一番情報が少ない
  • プロジェクトが始まるとわかってくることが多い
  • 何もわかってない状態で全てを決めないようにする

アーキテクチャは、常に選択肢を持つ

  • 仮説を持った上で取り組んで、それが当たればプラスで、外れれば負け
  • 将来は見れないからこそ、選択肢を持って柔軟に対応できるようにする

選択肢は、時間が経つと正しいかどうかが判断しやすい

  • オプションは、タイムトラベルとして扱える
  • 時間が経てば、答えがわかっていく
  • もっとキャパシティが必要ならさらに追加する
  • 意思決定を先延ばしにすると、後々判断に必要な情報を取得できる
  • ただ、全てに対して選択肢を持つのは費用的にはマイナス
  • 自分で積極的に選ぶ必要が出てくる

最適なアーキテクチャは、スナップショットでは得られない

  • 成長が今後見込まれるなら、よりスケールできるようにする
  • また、利用者の数がどのように変わっていくのか?によっても、必要なインフラの要件は変わる

アーキテクチャを判断するときのモデル

「どこを見てるのか?何が必要なのか?」を意識する

  • 意思決定は一つのモデルで完結しない
  • いいモデルは答えを出してくれる

全てに適用できるモデルは存在しないけど、幾つかのモデルを組み合わせば、ユースケースを表現できる。そのため、あらゆるユースケースに対応できるモデルを作ろうとしないことです。

汎用化の難しさ

マイクロサービスだと、それぞれのサービスで独自実装される場合が多いです。ここを、汎用サービスとして共通化できると、重複を減らせる

汎用化という定義の難しさ

  • 共通部分だけだと、各サービスだけで利用するデータが足りない
  • 和集合だと、ただ大きくなっただけになる
  • ここのちょうどいいバランスをとる

汎用システム作成時の5つのポイント

  1. なんでもできないけど、定めたユースケースはちゃんと満たせるようにする
  2. 汎用的なデータ構造設計が大切、出来ることを絞りつつ、どうやって複雑な要件を満たすか?
  3. 利用者への正しい理解を促進する。使えないシステムだとレッテルを貼られないために、どういうことをスコープしたサービスなのか?を理解する。また、社内でのコンサルの理解も大切
  4. オーナーシップが大切。汎用システムを一つのプロダクトとして捉えて、開発運用して行く
  5. 効果の定期的な見直し。作りっぱなしではなく、定量・定性的な所で、より見直して修正する

アーキテクトの役割

アーキテクトの役割は、全員よりも賢くなることではない。他の人たちをより賢くするためのもの。他の人達が意思決定に対して、主体性を持たせるのが一番大事です。

8. レジリエンスと運用(障害に強いシステム設計)

セキュリティ要件の重要性

セキュリティ要件は、クリティカルになりうります。そのため、サービスが小さいうちから意識して予防したり、安全に扱う仕組みを作ることが大切です。

同期・非同期の使い分け

即時性・即時整合性が必要なら同期。そうでないなら、スケールなどの観点から非同期の方が良さそうです。

同期トランザクション管理で、複数ネストする場合の対応方法

一番外側のトランザクションだけを適用します。

内部の処理で、複数のトランザクションが存在する場合、外側にトランザクションがあればそれを使う、ない場合は個別に作る

ドメインの特性から、必要なアーキテクチャ構成が変わる

保険や金融商品では、アクセス数少ないけど、整合性が大切、などドメインによって要件が異なります。

疎結合の2つの分離軸

  • 時間軸分離(いつ処理されるのか?)
  • 空間的分離(配置場所など)

あるコマンドを打った時に、それがどこで処理されるのか?などで時間を分離します。

同期呼び出しのトレードオフ

A, B, Cのサービスが順に呼び出す時は、可用性が落ちやすいです。A, B, Cでどれかが落ちたら、それでサービスが止まります。

Messageのアーキテクチャ

Messageのアーキテクチャで重要なのは、Fire And Forgetです。

相手に送った後は、次の処理に移る。それにより、Message送り先と送り元で疎結合にできます。

メッセージを受け取ったところで、一時的にデータをキャッシュできると、送り先が落ちたとしても処理を継続できます。

基盤サービスを作成するときの注意点

部分部分での最適なユースケースを考えたりするときも、元の事業ドメインとか必要な要件を考える必要があります。

クリティカルな要件であり、かつ共通化できるところは切り出す。これにより、実装漏れを減らすことができます。

マイクロサービスの運用課題

マイクロサービスは、トレースが難しくなります。エラーデバッグが大変になります。

モノレポの課題

モノレポの場合は、依存関係を考えるのが大変です。なので、一つのレポジトリを修正するのか、両方のレポジトリを修正するのか、で仕組みを変える必要があります。

モデル自体も、Mermaid形式のドキュメントで保存しておくと良いでしょう。共有モデルとか、依存関係とかを取得するためのMCPを作ると良さそうです。

レジリエンスとは?

どのようにパフォーマンスを出しているか、パフォーマンスが十分かどうかを定義しつつ判断するものであり、持っているか持っていないか、ではありません。

  • 障害が起きたとしても、何を継続し続けないとダメか?を意識する
  • 予期せぬことが起こる前提で、既知と未知のことに準備する

つまり、何か間違ったとしても、オペレーションが続くことが重要です。

レジリエンスエンジニアリングとは何か?

従来は、何も悪いことを起きないことが前提でした。ただ、故障するかもしれないという可能性を受け入れるのが重要です。

コンポーネントが複雑になればなるだけ、障害が起こる可能性が高くなります。一つのコンポーネントであれば故障を防げる。でも沢山含まれるようになると、どれか一つが故障する可能性が高くなります。

また人がミスをしてしまっても、リカバリーできるようにするのも重要です。

障害が避けられないからこそ、障害しても問題ない作りにするのが重要です。

色々なことに対応しようとすると、故障する可能性が増えていく、より複雑になっていく。これは、避けられない定めになります。

レジリエンスを考える上で重要な視点4つ

1. 堅牢性(Robustness)

何かこういうことが起きそう、と理解していて、それを事前に用意しておく。一つのものに対して、複数のインスタンスを作って故障しても問題ないようにする。

2. リバウンド(Rebound)

起きた後に、どれだけ早く回復できるか?障害が起きた時に、どれだけ早く戻れるか?

3. 美しい優雅な拡張性(Graceful Extensibility)

予期しない事態に、どれだけ深く対応できるか?全ての事象は予測できない、それが起きた時にどうやって対応していくか?を、長い時間をかけて準備していく。

4. 持続的な適用性(Sustained Adaptability)

システムは常に変化して、新しくする。次に備えていくのが大切。持続的な適用力は、進化や革新の機会になります。

ディケンソンのサービス可用性

開発や製品に注目されがちだけど、重要なのは「モニタリング」です。

なぜダメだったのか?をモニタリングしたり、原因分析を行うのが重要です。

障害の原因分析

ある障害が起こった時に、その原因を「技術」と「社会」の二つから確認します。

障害が起こったビジネスの状況や、人の状況に応じても変わります。つまり、一つの理由から問題が起こるのではなく、複数の原因がある場合が多いです。

「人が手順を間違えた」、それでも「システムは動き続ける」という状況・仕組みを作るのが重要です。

おわりに

Architecture Conference 2025 では、現代のソフトウェアアーキテクチャ設計において重要な多くの知見を得ることができました。

特に印象的だったのは、以下のポイントです:

  1. マイクロサービスは手段であり、目的ではない - 得られる価値を重視する
  2. モジュラーモノリスから始める - 徐々にマイクロサービスへ移行
  3. チーム構造とアーキテクチャは密接に関連 - コンウェイの法則を意識する
  4. AIは能力の増幅機 - 人間のスキルアップが前提
  5. 変更容易性が設計の本質 - 事業戦略と紐づけて判断
  6. レジリエンスは障害を前提とする - 障害が起きても動き続ける仕組み

最後に、素晴らしい講演をしていただいた講演者の皆様、カンファレンスをサポートしていただいたスポンサー企業の皆様、そして素敵なイベントを開催していただいたFindy様、本当にありがとうございました!
来年も必ず参加させていただきます!

GitHubで編集を提案

Discussion