こんにちは、ギフティでエンジニアをやっている中屋(@nakaryo79)です!
GiftExperince dev unit というチームに所属しています。 先日の社内 LT イベントで登壇する機会があり、ソフトウェアアーキテクチャについて発表しました。
最近、ギフティではシステムのリプレースや複数システム間の構成の見直しなどを行なっており、アーキテクチャに関わる話題が増えてきました。
また、社員の中でもその領域に興味を持つ人が増えてきて、有志でソフトウェアアーキテクチャ・ハードパーツの輪読なども行なっています。
自分も一時期レガシーシステムのリアーキテクチャリングのタスクを主にやっていたことがあり、その際に色々とインプットしたので、それをもとに自分なりの解釈を発表したという感じです。
以下が発表時のスライドです。
スライドではその場で口頭で話した情報などが抜け落ちていたり、発表時間の都合上割愛した部分もあったりするので、この記事ではその補足という意味合いで改めて文字にしてまとめてみました。
そもそもソフトウェアアーキテクチャという言葉が意味するところ
ソフトウェアアーキテクチャについてインプットし始めた頃は、そもそもソフトウェアアーキテクチャという言葉が何を指しているのかわかりませんでした。 そして、インプットするほどよくわからなくなっていきました笑
この記事では、以下のようなことが書いてあります。
- ソフトウェアアーキテクチャはあなたが思っているものとは違うかもしれない
- 構造を記述することではなく、意思決定を把握すること
- アーキテクティングはアジャイルチームが具現化するスキルであり、役割ではない
これを読むに、具体的なアーキテクチャパターンの話ではなく、もう少し抽象的な概念だと考えられます。
さらに、いくつかの書籍に書いてある定義を引用してみます。
ソフトウェア・アーキテクチャはとても複雑だ。 そのせいで、専門家たちがさまざまな定義を生み出しているが、受け手にとってみればどれも一長一短である。 (中略) ほとんどのアーキテクチャ本では、アーキテクチャ上の設計プロセスにおける人間的要素を削りすぎている。
ソフトウェアアーキテクチャとは、望まれる品質特性やその他の性質を促進するためにソフトウェアをどう構成するかということに対する、重要な設計判断が集まったもの。
システムの構造、システムがサポートしなければならないアーキテクチャ特性、アーキテクチャ決定、そして設計指針の組み合わせで構成されるもの。
アーキテクチャとは、絶え間ない懸命な取り組みの一つである。 プログラミングと密に連携し、変化する要件に対応するだけでなく、プログラミングがもたらすフィードバックにも対応できるようにする取り組みだ。
これらを見るに、これといった統一された定義がなく、そもそも何を対象とするか、というのも決まりきったものがないように感じられます。 また、アーキテクチャといった時に連想されがちなモノリスやマイクロサービスなどのシステム構成の話でもなさそうだということがわかります(実際に、『ソフトウェアアーキテクチャの基礎』では、それらはシステムの構造の話であって、システムのアーキテクチャの話ではない、とわざわざ書いてあります)。
中々捉えどころのない概念に思えますが、むしろそのぐらいフワッとしたものに取り組むというのがソフトウェアアーキテクチャについて考えるということなのかなと理解しています。 ということで、現時点で自分なりに整理したソフトウェアアーキテクチャの定義を以下にまとめます。
- 望まれる品質特性に対する重要な設計判断(トレードオフ)の集合
- 絶え間ない継続的な活動
- より良いソフトウェアをより長きに渡って使えるようにし、ユーザー体験、開発者体験、ビジネスをドライブさせる取り組み全般を指す
- ソフトウェアアーキテクチャについて考えるということは、ソフトウェア開発のあらゆるトレードオフについて考えるということである
ソフトウェアアーキテクチャについてなぜ「今」考えるのか
実はソフトウェアアーキテクチャという考え方自体は半世紀以上前、ダイクストラの時代からあったそうです。 では、なぜ今それについて考えることが大事なのか。
ソフトウェアそのものの価値の高まり
一つはソフトウェアそのものが占める、世の中へのインパクトの比重が高まっていることが挙げられます。 マーク・アンドリーセンが言ったように、あらゆるものがソフトウェアに飲み込まれていく時代になってきており、企業の時価総額ランキングでも上位を占める企業の多くのがテックカンパニーとなっています。
また、2022年には以下の2冊の書籍が発売され、巷でもアーキテクチャに関する関心の高まりが感じられます。
変化のスピードの早さ
二つ目は変化のスピードの早さです。
ソフトウェアの世界は技術の移り変わりが早く、今作ったものが数年後には既に陳腐化している可能性は大いにあります。 また、ソフトウェア自体は本質的にはコピー可能なものです。そのため、より早い変化に対応する必要があります。
他にもアジャイルアプローチによる高速フィードバックサイクルに対応できるためには、アーキテクチャという土台がしっかりしていなければなりません。 より不確実性の高いマーケットにいるプレーヤーにとっては、その重要性はより高まると思います。
マシンリソースの潤沢さ
従来は、マシンが高価な上に買い切りであることから、柔軟な構成を取りたくてもそもそも予算面や統制面で難しい場合があったかもしれません。 それが、ハードウェアの性能向上であったり、クラウドコンピューティングによってオンデマンドでインフラを調達できるようになったことで、インフラの面でより多くの選択肢が取れるようになってきました。それに合わせてマイクロサービスアーキテクチャなどが実現できるようになってきたという背景があります。
分散システムにおけるエコシステムの充実
マイクロサービスなどの考え方を筆頭に、分散トランザクションやイベントソーシング、コンテナオーケストレーションなどのエコシステムが充実してきています。 様々な取り組みの公開された知見も増えてきて、モノリシックアプリケーション以外の選択肢にチャレンジしやすい環境が整いつつあると言えるのではないでしょうか。
モノリシックアーキテクチャの限界
事業がグロースすればするほど、ソフトウェアの規模も(比例はしないですが)当然大きくなる傾向にあります。 そして、規模が大きくなればなるほど認知負荷やコミュニケーションの問題から保守運用の難易度が上がります。 また、ユースケースがほぼ固定化されている領域であれば問題ないかもしれませんが、不確実性の高い領域では思いも寄らないユースケースや事業が後から発生するかもしれなく、密結合したモノリスではそこへの対応が最悪の場合できないかもしれません(モノリスが悪いというわけではなく、そういう考え方で作ると変化に対応できるモデリングにならない可能性がある、という話です)。 そうすると、ソフトウェア規模の拡大に合わせた何らかの秩序が必要になってきます。それについて考えるのがソフトウェアーキテクチャという分野なのだと思います。
ソフトウェアアーキテクチャがなぜ重要か
ソフトウェアの長寿性
まず、ほとんどの場合、ソフトウェアは、それを構築したチームよりはるかに長く存続します。 ソフトウェア開発界隈の人材流動性は低くはないですし、10年、20年と続くソフトウェアの開発を全く一緒の人間が開発していくことはまずないのではないでしょうか。さらに悪いことに、初期の立ち上げに関わった人がもはや誰もいない、という状況も普通に起こりうると思います。 そうしたソフトウェアのライフサイクルの中で数多のステークホルダーが関わります。 アーキテクチャという土台、指針が優れていないと長期にわたって明らかな負債を抱えることになります。
ソフトウェアの安定性
また、良いアーキテクチャは、安定性を高めます。 安定した土台があれば、多くの無駄を省き、多くの利益が得られます。 変更が容易であればあるほど、より早くより多くのユーザーにメリットを提供できます。
Lisp の天才プログラマである Paul Graham は自伝的エッセイである『ハッカーと画家』の中で、以下のように述べています。
ソフトウェアビジネスは極めて競争の激しい業界。 ある会社が他の会社より、他が同じ条件で、より良いソフトウェアをより速く書いたとしたら、他の会社はいずれ潰れる。
良いアーキテクチャによって、保守性、拡張性が保たれていれば、他社より早く機能をマーケットに提供していくことができ、それが競争優位性に繋がります。
アーキテクチャの社会的構造への影響
アーキテクチャは、社会的構造に影響を与えます。 社会的構造とは組織やチームを指します。 どんな技術的要素を選択したとしても、それを使えるように開発チームを作っていくしかありません。 アーキテクチャによって組織ケイパビリティが形作られ、その組織によって次のアーキテクチャが決定づけられていきます。 優れたアーキテクチャは採用競争力を生み、優れたアーキテクト、エンジニアへの求心力となります。
模倣容易性
ソフトウェアはいくらでもコピー可能ですが、優れたアーキテクチャは、模倣しづらいです。 企業が置かれている状況は様々であり、アーキテクチャを模倣したとてそれがその組織体でワークするかは定かではありません。コードそのものはコピーできたとしても、アーキテクチャはその時の人材状況、マーケットでの立ち位置、経営戦略、競合の動向などなどを鑑みて設計していく必要があります。 故に、ソフトウェアアーキテクチャは簡単には模倣できず、それ自体が競争優位性を生みます。
ソフトウェアアーキテクチャが向き合う課題
アーキテクチャとは Google で答えが見つからないものだ -- Mark Richards
組織が直面する問題は、事業ドメインや組織の置かれている状況によって様々です。 ソフトウェアアーキテクチャは特定の課題に対する答えを出してくれるものではなく、用意された答えがないものに対してどのように対応していくかを考えるためのものです。
また、『ソフトウェアアーキテクトが知るべき97のこと』には以下のようなことが書いてあります。
- 未来永劫安泰なソリューションはない
- 未来を予言できる人はいない
- 今下したアーキテクチャ上の判断は、何であれ、いずれ時代遅れになる
状況というのは刻一刻と移ろうので、どんなソリューションもいずれ陳腐化していきます。 絶対的な正解はなく、あるのはその時点でのトレードオフだけというわけです。
では、トレードオフをどう分析したらいいのか。
色んな手法があると思いますが、ここではその中の一つである 品質特性 という概念に目を向けてみます。 品質特性はアーキテクチャ特性や品質属性などとも呼ばれたりしますが、それによって良し悪しを可視化する、つまりソフトウェアの通知表をつけてみよう、ということです。
品質特性を説明するときに便利な Architectural Drivers という概念があります。
Architectural Drivers の一要素として品質特性というものが定義されています これはいわゆるソフトウェアの〇〇性(-ility)と呼ばれるものの総称だと思ってもらって大丈夫です。 この図では代表的なものとして可用性、変更容易性、性能・速度、堅牢性、テスト容易性、使いやすさを挙げていますが、他にも様々な特性があります。 この品質特性を評価することで、ソフトウェアの良し悪しをある程度定量的に表す足がかりにすることができます。
具体的な手法の話を書き始めると長くなるので、ここではざっくりと、評価の仕組みを作っていく順序を説明します。詳しくはまた別の記事に譲りたいと思います。
品質特性を適用する対象を決める
まずは適用する対象を決めます。
プロダクトによって優先したい品質特性は変わってきます。自社の全てのプロダクトに一律で適用するというものではなく、中にはパフォーマンスが重要な場合もあれば、セキュリティが重要なものもあるはずです。また、計測にはそれなりのコストがかかるため、それがペイできないようなプロダクトに適用しても意味がないです。
よって、最初にこれから考える品質特性をどのスコープに適用するか、を決めます。
その際、巨大な泥団子では個別最適化した品質特性を定義できない可能性があるので、適切な粒度でアプリケーションを分割する必要があるかもしれません。 その場合、まずはアプリケーションの結合を明らかにして、適切な粒度に分解していくという作業を行います。
品質特性を定義する
スコープが決まったら、自分達が大事にしたい品質特性を決め、優先順位をつけます。 全ての特性に対して高い水準を同時に追い求めるのは不可能ですし、品質特性の中には、同時に実現するのが難しいものがあります。 例えば、簡単なものでも以下のようなトレードオフが挙げられます。
- 可用性を上げるために冗長構成にするとコストが嵩む
- セキュリティのために暗号化などの処理を入れると速度性能が落ちる
自分達が作ろうとしているプロダクトにおいて、どの特性が重要になるか、どの特性を守りたいか、というのをエンジニアだけでなくビジネスサイドも含めて全員で検討します。全ての特性に対して検討するのは難しい(そもそも計測するコストがかかりすぎる)と思うので、重要そうなものにいくつか目星をつけて少しずつ検討していくと良さそうです。
品質特性を守る
守りたい特性を定義できたら、それを継続的に守っていく仕組みを作ります。
守るためにはまず測る必要があります。 最初は手動での計測から始め、できれば自動化できると良さそうです。 品質特性に対する適応度(ある品質特性がどの程度満たされているかを評価する客観的な指標)関数を作り、CI などで自動化することができれば抜け漏れなく、低コストで評価を行うことができます。
この適応度関数の話は、『進化的アーキテクチャ』などの書籍に詳しく書いてあります。
終わりに
アーキテクチャについて深い洞察を持って議論するにはそれ相応の知識と経験が必要に思えます。品質特性の評価などの必要性も「理論上はわかるわかる、そうだよね」という状態にはなってはいるものの、中々実際のプロダクト開発にそうした仕組みを導入していくまでには至っていません。
冒頭にも書きましたが、ギフティでは社内システムのリアーキテクチャも進んでいます。 また、toC のカジュアルギフトから始まった弊社のeギフト事業ですが、今では法人向けの事業や地域通貨など地方自治体向けの事業など、その応用は多岐に渡ります。 日本のeギフト市場はまだまだ新しい事業可能性を大いに秘めている、不確実性の高い事業領域だと思います。より良いアーキテクチャを土台に、システムと事業を作っていく必要性がどんどん高まっていると感じています。
ギフティではソフトウェアのアーキテクチャについて考えるアーキテクトを絶賛募集中です。というかエンジニアリング全般の職種を募集中です。 気になる方は、是非一度カジュアル面談でもなんでも良いので一度お話ししましょう!