1. エグゼクティブサマリ
ソフトウェアアーキテクチャについて調べると、それぞれの構造やメリット・デメリットを解説した情報は数多く見つかります。一方、実際のプロジェクトでは「どのアーキテクチャが優れているか」を知るだけでは、技術選定はできません。プロジェクトの目的や制約、開発メンバーの経験などを踏まえ、「なぜ、このプロジェクトではこのアーキテクチャを選ぶのか」を判断する必要があります。
私が携わったプロジェクトでは、バックエンドにLayered Architecture、フロントエンドにFeature-based Architectureを採用しました。大きな理由の一つは、過去のプロジェクトで本番導入まで経験しており、設計や実装で発生する課題をある程度予測できたことです。新しいアーキテクチャを採用することよりも、過去の経験を活用して意思決定や手戻りにかかるコストを抑え、プロダクト固有の課題に時間を使うことを優先しました。
本記事では、この意思決定をケーススタディとして振り返ります。特定のアーキテクチャの優劣を論じるのではなく、プロジェクトの状況と自分たちが持つ経験をどのように判断材料として捉えたのかを整理し、「ベストプラクティスを選ぶ」のではなく「プロジェクトにとってのベストを考える」という技術選定の一例を紹介します。
2. プロジェクトの背景と課題
今回扱うのは、私が実際に開発に携わったプロジェクトでの経験です。プロジェクト固有の情報については触れませんが、アーキテクチャを選定するうえで重要だったのは、新しいアーキテクチャを検証すること自体がプロジェクトの目的ではなかったという点です。
プロジェクトでは、限られた時間の中で必要な機能を実装し、プロダクトとして価値を提供する必要があります。そのため、アーキテクチャを含むすべての技術要素で新しい挑戦をするのではなく、どこに時間を使うべきかを考える必要がありました。
一方、アーキテクチャには複数の選択肢があります。バックエンドであればLayered ArchitectureやClean Architectureなど、さまざまな設計思想が存在します。私自身も複数のアーキテクチャについて学習していたため、新しい構成を実際のプロジェクトで採用することも選択肢の一つでした。
しかし、今回の目的から考えると、「どのアーキテクチャが一般的に優れているか」よりも、**「どのアーキテクチャであれば、不確実性を抑えながらプロジェクトを進められるか」**を考える方が重要でした。そこで、アーキテクチャそのものの特徴だけではなく、自分たちが持っている経験も含めて選定することにしました。
3. アーキテクチャ選定で重視したこと
3.1 「経験」を判断材料として考える
今回の選定において重要な判断材料となったのが、過去の開発経験です。私はこれまでのプロジェクトで、バックエンドのLayered ArchitectureとフロントエンドのFeature-based Architectureを使った開発に携わり、本番導入まで経験していました。
ここで重要なのは、単にアーキテクチャについて「知っていた」ということではありません。実際のプロジェクトで利用した経験があったため、どこに何を実装するのか、どのように責務を分けるのか、機能追加時にどこを変更するのか、どのような場面で設計に迷いやすいのかを、ある程度予測できる状態でした。
もちろん、過去に利用した経験があるからといって、今回のプロジェクトでもそのアーキテクチャが最適だとは限りません。しかし、経験によって設計や実装における不確実性を下げられるのであれば、「経験があること」自体を技術選定における一つの判断材料として捉えることができます。
3.2 新しいアーキテクチャには「意思決定コスト」がある
新しいアーキテクチャを採用することにも、当然メリットがあります。学習した知識を実践できますし、新しい設計を経験することで、チームや個人の技術的な選択肢を増やせる可能性があります。
一方、実際のプロジェクトで採用する場合は、学習や実装以外にもコストが発生します。例えば、「この処理はどこに置くべきか」「どこまで責務を分離するべきか」「一般的な原則を今回の要件にどう適用するか」といった判断が必要になります。経験の少ない構成であれば、その都度調査や議論が必要になり、実装後に設計上の問題が分かれば手戻りも発生します。
つまり、新しいアーキテクチャを採用するコストには、学習時間や実装工数だけではなく、調査する時間、判断する時間、そして手戻りする可能性も含まれます。今回のプロジェクトでは、この「意思決定に必要な時間」も技術選定におけるコストの一つとして考えました。
3.3 新規性よりも予測可能性を優先する
以上を踏まえ、今回のプロジェクトでは、アーキテクチャの新規性よりも開発における予測可能性を重視しました。未知のアーキテクチャを採用して技術的な経験を広げることよりも、過去の経験を活用して設計や実装の不確実性を下げ、その分の時間をプロダクト固有の課題に使う方が、プロジェクトの目的に合っていると判断したためです。
これは、新しい技術やアーキテクチャを避けるという意味ではありません。プロジェクトには期間や人的リソースなどの制約があるため、すべての技術要素で新しい挑戦ができるわけではありません。そのため、「どこで新しい挑戦をし、どこで既存の経験を活用するのか」を決めることも、技術選定の一部だと考えました。
4. 意思決定と採用したアーキテクチャ
今回の判断を整理すると、「過去に使ったことがあるから同じものを使う」という単純なものではありません。まず、プロジェクトの目的を踏まえると、アーキテクチャ自体の検証に多くの時間を使う必要はありませんでした。次に、過去に本番導入まで経験した構成であれば、設計や実装における不確実性を下げられると考えました。その結果、経験を活用することで意思決定や手戻りにかかるコストを抑え、プロダクト固有の課題により多くの時間を使うことを優先しました。
この判断から、バックエンドにはLayered Architecture、フロントエンドにはFeature-based Architectureを採用しました。
4.1 Backend:Layered Architecture
バックエンドではLayered Architectureを採用しました。選定理由は、Layered Architectureが他のアーキテクチャよりも優れていると考えたからではありません。過去の開発経験を通じてレイヤーごとの責務や依存関係について一定の理解があり、機能追加時にも「この処理をどこに置くか」「どのレイヤーが責務を持つか」といった判断を行いやすかったためです。
つまり、今回のプロジェクトにおいて、Layered Architectureは自分たちが扱いやすく、設計や実装の予測可能性を高められる構成だったことが主な採用理由です。
4.2 Frontend:Feature-based Architecture
フロントエンドではFeature-based Architectureを採用しました。コンポーネントやhooksなどを機能単位で整理する構成について過去の開発経験があり、機能追加時にどの単位でコードを配置するかをイメージしやすかったためです。
こちらもバックエンドと同様に、Feature-based Architectureそのものをベストプラクティスとして採用したわけではありません。過去の経験を活用することで、ディレクトリ構成や責務の配置について試行錯誤する時間を減らし、機能開発に意識を向けやすくすることを重視しました。
5. 採用後の結果と振り返り
実際に開発を進めた結果、アーキテクチャそのものについて大きく迷う場面を抑えながら開発を進めることができました。新しい機能を実装するときにも、過去の経験をもとにコードの配置や責務を判断できたため、アーキテクチャに関する基本的な意思決定を繰り返す必要が少なくなりました。
もちろん、すべての設計判断がなくなったわけではありません。プロジェクト固有の要件や新たに発生した課題については、その都度検討が必要でした。しかし、既に経験している領域での意思決定を減らしたことで、プロジェクト固有の問題に対して、より多くの時間を使える状態を作れたことは、今回の選択によるメリットだったと考えています。
その意味では、当初重視していた「予測可能性を高める」という目的に対して、今回の選択は一定程度機能しました。一方で、これはLayered ArchitectureやFeature-based Architectureを採用すれば同じ結果になるという意味ではありません。今回の結果には、自分たちが過去にこれらの構成を経験していたという前提があります。
6. ケースから得られた示唆
6.1 「経験があるから選ぶ」は、必ずしも消極的な判断ではない
今回の経験を振り返る中で、一つの問いが残りました。それは、「経験したことがあるから採用する」という理由は、技術選定として弱いのではないかというものです。新しいアーキテクチャを採用する方が、技術的には積極的な選択に見えることもあります。
しかし、プロジェクトには期間や人的リソースなどの制約があります。経験したことのあるアーキテクチャを利用することで、学習や設計判断に使う時間を減らし、その分をプロダクト固有の課題に使えるのであれば、それは合理的な選択になり得ます。重要なのは「知っているから選んだ」で終わるのではなく、その経験を利用することがプロジェクトにどのような価値をもたらすのかを説明できることです。
6.2 ベストプラクティスと、プロジェクトにとってのベストは異なる
今回のケースから得た最も大きな示唆は、一般的なベストプラクティスと、そのプロジェクトにとってのベストは必ずしも一致しないということです。アーキテクチャにはそれぞれメリットとデメリットがあり、どのメリットを重視し、どのデメリットを受け入れられるかは、プロジェクトの目的や制約によって変わります。
そのため、「一般的にどのアーキテクチャが優れているのか」という問いだけでは、実際の技術選定には十分ではありません。「このプロジェクトでは何を優先するのか」「その優先順位に対して、この選択を説明できるのか」という問いを持つことが重要です。
6.3 再利用するべきなのは「答え」ではなく「意思決定の考え方」
今回Layered ArchitectureとFeature-based Architectureを採用したからといって、次のプロジェクトでも同じ構成を採用するとは限りません。プロジェクトの規模、チーム構成、運用期間、求められる品質特性、チームが持つ経験などの条件が変われば、別のアーキテクチャが適切になる可能性があります。
したがって、今回のケースから再利用したいのは「Layered ArchitectureとFeature-based Architectureを選ぶ」という答えではありません。プロジェクトの目的と制約を整理し、技術的な特徴だけでなく自分たちの経験も判断材料に含め、なぜその選択をするのかを説明するという意思決定の考え方です。
7. おわりに
アーキテクチャ選定では、「どのアーキテクチャが最も優れているのか」に目が向きがちです。しかし、実際のプロジェクトでは、技術的なメリット・デメリットだけでなく、期間、チーム、経験、学習コスト、意思決定に必要な時間など、さまざまな要素を考慮する必要があります。
今回のプロジェクトでは、過去に本番導入まで経験したアーキテクチャを採用することで、設計や実装における不確実性を下げ、プロダクト固有の課題により多くの時間を使うことを優先しました。「新しいアーキテクチャを採用しなかった」という選択ですが、プロジェクトの目的から逆算すれば、それも一つの技術的な意思決定だったと考えています。
アーキテクチャ選定で重要なのは、「正しいアーキテクチャ」を探すことではなく、プロジェクトの目的と制約を踏まえて「なぜこの選択をするのか」を説明できることです。そして、条件が変われば、その判断を改めて見直す必要があります。今回の経験を通じて、このプロセスこそが「プロジェクトにとってのベスト」を考えることなのだと感じました。