ソフトウェアアーキテクチャ()は、ソフトウェアコンポーネント、それらの外部特性、またそれらの相互関係から構成される。また、この用語はシステムのソフトウェアアーキテクチャの文書化を意味することもある。ソフトウェアアーキテクチャの文書は開発依頼主とのコミュニケーションを容易にするもので、概要レベルの設計に関する早期の決定を促し、プロジェクト間でのコンポーネントとパターンの設計を再利用することを可能にする。
背景 計算機科学の分野は、その草創期から複雑性に関する問題を扱ってきた。初期の複雑性の問題は、開発者が正しいデータ構造を使い、アルゴリズムを開発し、問題を分割する手法を用いることによって解決されていた。その一方で、「ソフトウェアアーキテクチャ」という用語は、業界でも比較的新しいものである。その分野の根本原理は、1980年代ごろからソフトウェア工学の先駆者たちによって散発的に適用されてきた。そのため、システムのソフトウェアアーキテクチャを説明する初期の試みは、不正確で混乱したものであった(四角形と線で描かれた図など)。1990年代、ソフトウェアアーキテクチャの根本的な記述方法の成文化が集中的に行われた。その結果、初期のデザインパターン、ベストプラクティス、記述言語、形式論理などが開発された。
ソフトウェアアーキテクチャとは、抽象化と問題の分割によって複雑性を減らすことを主に念頭に置いたものである。ただし、今までのところ「ソフトウェアアーキテクチャ」という用語に関して、万人が合意した厳密な定義は存在しない。
ソフトウェアアーキテクチャは、分野としては円熟してきていながらも、明確な規則がない。そして、技術者はそのような環境の中でシステムを設計しなければならないため、その作業は未だに科学と技能の混合となっている。ソフトウェアアーキテクチャの「技能」的側面は、商用ソフトウェアシステムがビジネスに使用されているという点によるところが大きい。また、システムがビジネスの重要な一部を担っているため、システムの要求仕様は機能仕様ではなく、品質レベルなどで記述されることが多い。システムは、ビジネスの性質に依存するため千差万別であり、品質特性のレベルもシステムによってさまざまである。例えば、フォールトトレラント性が求められたり、互換性が重視されたり、拡張性、信頼性、保守性、可用性、情報セキュリティ、ユーザービリティなどといった面が重視されたりする。
ソフトウェアアーキテクチャは、システムが備えるべき複数の洞察の混合物である。そのようないくつかの観点がソフトウェアアーキテクチャに組み込まれるということは、ソフトウェア開発が具体化する前に、ソフトウェアアーキテクチャを作成することの正当性を示している。
アーキテクチャの記述法 アーキテクチャ記述言語 アーキテクチャ記述言語(ADL) は、ソフトウェアアーキテクチャを記述するための言語である。これまで、いくつかの ADL がそれぞれ異なる組織によって開発されてきた。例えば、Wright(カーネギーメロン大学)、Acme(カーネギーメロン大学)、xADL(UCI)、Darwin(インペリアル・カレッジ・ロンドン)、DAOP-ADL(マラガ大学)などがある。また、ADL の基本要素として、コンポーネント、コネクター、コンフィギュレーションなどがある。
ビュー ソフトウェアアーキテクチャは、一般に複数のビュー(Views)で構成される。これは、建築で複数のさまざまな設計図が使用されるのに似ている。ANSI/IEEE 1471-2000によれば、ビューはビューポイント(viewpoints、観点)のインスタンスであり、ビューポイントとはそのシステムの関係者がそれぞれの立場で必要とするアーキテクチャを記述したものである。
以下のようなビュー(1471 ではビューポイント)がある。
機能/ロジックビュー コードビュー 開発/構造ビュー 並列性/プロセス/スレッドビュー 物理/配置ビュー ユーザー行動/フィードバックビュー
ソフトウェアアーキテクチャを記述するための言語は、いくつか考案されているが、どれも広く受け入れられてはいない。
アーキテクチャのフレームワーク
Department of Defense Architecture Framework (DODAF) MODAF The Open Group Architecture Framework (TOGAF) ザックマンフレームワーク Federal Enterprise Architecture (FEA) 現代ソフトウェアアーキテクチャの変遷
変遷
モノリシックアーキテクチャ 1950年代から1960年代のメインフレーム時代に主流だった設計手法にモノリシックアーキテクチャがある。モノリシックアーキテクチャとは、ユーザーインターフェース(UI)、ビジネスロジック、データアクセス層などの全機能が密結合し、単一のアプリケーションとして同一メモリ空間で動作する構造を指す。この構造は通信オーバーヘッドがなく、デプロイが単純であるという利点を持つ反面、一部の変更が全体に波及するため、軽微な修正でもシステム全体の再構築が必要になるという欠点があった。これは後のウォーターフォール型開発の硬直性として批判される要因となった。
1960〜1970年代、goto文の多用によるスパゲッティコードが問題となる。この問題に対し、1966年、ベームとヤコビーニによる「構造化定理」に基づき、「順次」「選択」「繰り返し」という3つの基本制御構造のみでプログラムを記述する「構造化プログラミング」が提唱される。
概念としてのソフトウェアアーキテクチャの起源は、1968年のエドガー・ダイクストラの研究や1970年代初期のデイビッド・パーナスの研究である。科学者たちは、ソフトウェアシステムの構造が重要であり、構造を正しくすることが肝要であることを強調した。
1970年初頭、ベル研究所のダグラス・マキルロイによって「パイプとフィルター」という概念が提唱される。これは、データ処理を独立した「フィルター」に分割し、「パイプ」で接続してストリーム処理を行う。各フィルターは独立しており、相互の存在を知らないため再利用性が高い。この概念は現代のETLツールやマイクロサービスにおけるパイプライン処理の基礎となっている。Unix哲学「一つのプログラムは一つのことをうまくやる」を体現したアーキテクチャである。
1970年代後半に入ると、複雑化する業務要件をシステムに反映させるため、英国でラリー・コンスタンチンやエド・ヨードンらが構造化分析設計手法(SSADM:Structured Systems Analysis and Design Method)を提唱した。SSADMは、データフロー図(DFD)や論理データ構造(LDS)などの図解と詳細な文書を用いて業務プロセスをモデル化する手法であり、1980年代に普及した。しかし、SSADMにはアーキテクチャ上のパラドックスが存在した。設計段階ではモジュールベースの分析を行うものの、当時のハードウェアやコンパイラの制約により、実装およびデプロイメントの段階では単一の実行可能ファイル(モノリシック)として構築せざるを得なかったのである。
また、同時期、プラグインアーキテクチャの概念が誕生する。マイクロカーネルパターンとも呼ばれ、システムを最小限の「コア」と拡張機能の「プラグイン」に分離する。これにより、コアシステムを変更することなく機能を拡張でき、開放/閉鎖原則を実践できる。この時期においても、Unisys VS/9オペレーティングシステム上の「EDT」テキストエディタに実装例が見られている。なお、その後も、1980年代後半にApple Macintosh向けの「QuarkXPress」にプラグイン機能が導入されるようになるなど、PCソフトウェアの設計に普及した。現在でも、ウェブブラウザ(FirefoxやChrome)など、多くの種類のアプリケーションで一般的な設計パターンとなっている。
1990年代初期には、アーキテクチャ上のスタイル(パターン)、アーキテクチャ記述言語、アーキテクチャの文書化、形式手法などが主に研究されるようになった。カーネギーメロン大学やカリフォルニア大学アーバイン校(UCI)など多数の研究機関がソフトウェアアーキテクチャの研究を行っている。カーネギーメロン大学の Mary Shaw と David Garlan の著書 Software Architecture: Perspectives on an Emerging Discipline(1996年)で、コンポーネント、コネクター、スタイルといったソフトウェアアーキテクチャ上の概念を提唱した。UCI の Institute for Software Research では、アーキテクチャ上のスタイル、アーキテクチャ記述言語、動的アーキテクチャなどを主に研究している。
ANSI/IEEE 1471-2000: Recommended Practice for Architecture Description of Software-Intensive Systems(ソフトウェアシステムのアーキテクチャ記述のための指針)は、ソフトウェアアーキテクチャの領域での世界初の標準であり、2000年9月、IEEE-SA標準化委員会が、IEEE Std 1471-2000 としてその標準を承認した。
クライアントサーバモデルと三層アーキテクチャ 1979年、Xerox PARCはMVC (Model-View-Controller)を考案。MVCは、Web開発(Strutsなど)においては、コントローラがリクエストを受け、モデル(DB)からデータを取得し、ビュー(HTML)を返すサーバサイドでの関心の分離として機能した。
1980年代後半、PCの性能向上に伴い、プラグインアーキテクチャーの処理を端末側に分散させるクライアントサーバモデルが主流となった。これは2層アーキテクチャとも呼ばれた。このアーキテクチャでは、クライアントPCにリッチなUIとロジックを配置し、DBサーバと直接通信を行った。しかし、ビジネスロジックの変更時に全端末への再配布が必要となる「デプロイメントの悪夢」や、DB接続数の限界、セキュリティが課題となった。
1980年代後半から1990年代にかけてのC++やSmalltalk、Javaが台頭した。これは、クライアントサーバモデルにおいて、処理能力を増したクライアント端末(PC)が、高度なGUIや複雑なビジネスロジックを担うようになると、従来の手続き型言語では状態管理が困難となり、カプセル化や継承によって複雑性を制御できるオブジェクト指向設計が不可欠となったためである。この分散環境への移行期において、1994年にGoF(Gang of Four)が体系化した『デザインパターン』は決定的な役割を果たした。例えば「Proxy」パターンがネットワーク越しのサーバ通信を透過的に扱い、「Observer」パターンがGUIのイベント処理を整理するなど、パターン群は単なるコードの作法を超え、クライアントとサーバが協調する分散システムの複雑さを実装レベルで解決するための共通言語として定着した。
1990年代後半~2000年代初頭にかけて、クライアントサーバ間の通信をより抽象化し、ネットワーク上の異なるマシンにあるオブジェクトをあたかもローカル環境にあるかのように扱う分散型アーキテクチャが普及した。その代表格として、OMGが策定したCORBAやマイクロソフトのDCOM(Distributed Component Object Model)がある。これらは野心的な試みであったが、ネットワーク遅延による性能劣化などにより、一過性の普及に留まった。
2000年初頭、中央集権的な制御を行わず、ノード同士が対等にリソースを共有するモデルであるピアツーピア(P2P)が誕生。単一障害点(SPOF)を排除できる特徴を持ち、ファイル共有ソフト(Napster, Winny)などが開発された。現代でもブロックチェーン技術の基盤となっている。
2000年代になると、 Web技術の普及により、プレゼンテーション、ビジネスロジック、データ管理を分離する三層アーキテクチャが確立された。これは、「プレゼンテーション層」「アプリケーション層」「データ層」とアーキテクチャを三層に分けることで、クライアントサーバの課題であった保守性やセキュリティ対策を向上させた。三層アーキテクチャは、2025年現在でも採用されている。
クラウドネイティブとAPIエコノミー アーキテクチャが複雑化に対応する概念として、2005年にAlistair Cockburnによって、ヘキサゴナルアーキテクチャ(ポート&アダプタ)が提唱される。これは、ビジネスロジックを、外部の技術詳細(UI, DB, 他サービスなど)から分離し、疎結合に保つための概念である。六角形の中心にビジネスロジックのコアを置き、ポートとアダプターを介して外部と通信することで、テスト容易性、保守性、拡張性を向上させ、ビジネスロジックが外部環境に依存しないように設計される。
これと同様の概念として、クリーンアーキテクチャがある。これは、2012年にロバート・C・マーチンが提唱したソフトウェア設計手法で、ビジネスロジックをフレームワークやデータベース、UIといった外部の技術的詳細から完全に独立させることを目的としている。クリーンアーキテクチャも、同心円状のレイヤーで構成され、内側から外側への一方向の依存関係を持つことで、テスト容易性、保守性、拡張性を向上させている。クリーンアーキテクチャには、「ユースケース層」があり、この層により具体的な役割分担と依存関係の明確化をはかる。
分散型アーキテクチャからマイクロサービスアーキテクチャ 2000年代初頭、異種システムを統合するためにSOA (Service Oriented Architecture)が提唱された。エンタープライズサービスバス(ESB)を中核とし、SOAP等の標準技術を用いたが、ESBが肥大化しボトルネックとなる問題が生じた。
2000年、Roy Fieldingは、REST(Representational State Transfer)を発表。リソース中心の設計とJSONの採用により、フロントエンドとバックエンドの分離を決定づけた。その後、RESTの原則に従ったAPIの設計・実装を実現する、RESTful APIが誕生し、WebAPIの標準的な手法となった。
RESTには過剰なデータを取得したりアンダーフェッチする問題があった。これを解決するため、2012年、Facebookはクライアントが必要なデータ構造を指定できるGraphQLを開発した。
2000年、エリック・ブリュワーはPODC会議にて「CAP定理」を提唱。分散システムにおいて一貫性(Consistency)、可用性(Availability)、分断耐性(Partition Tolerance)の三つを同時に満たすことは不可能であると主張し、厳密なACID特性への固執は物理的な制約であると発表。2006年のGoogle Bigtableや、2007年のAmazon Dynamoの論文発表が決定打となり、2000年代後半から2010年代にかけて、可用性と拡張性を最優先するNoSQLデータベースが普及した。
クライアント側のUI設計パターンとして、2005年頃にマイクロソフトがMVVM (Model-View-ViewModel)を導入。ViewModelがView(UI)とModel(データ)を仲介し、データバインディングによって双方の状態を自動的に同期させる点が特徴である。これにより、開発者はDOM操作などの低レベルな処理から解放された。
2010年代、サービス間をREST API等の同期通信がボトルネックとして顕在化した。この解決策になったのが、LinkedInが開発し、2011年にオープンソース化されたApache Kafkaのようなデータの高速中継技術であるメッセージブローカーであった。これらの技術基盤が成熟したことで、システム内で起きた状態の変化をイベントとして非同期に伝え合うイベント駆動アーキテクチャ(EDA)が誕生した。また同時期に、データの更新処理とクエリをモデルレベルで分離するCQRS(コマンド・クエリ責務分離)が注目され、マイクロサービスに標準的な設計パターンとして広く定着していった。
2014年にマーチン・ファウラーらによって、マイクロサービスアーキテクチャが提唱される。これは、システムを「独立してデプロイ可能な小さなサービスの集合体」として構築するスタイル。SOAとは異なり、「賢いエンドポイントと単純なパイプ」を志向し、各サービスが独自のデータベースを持つことで結合度を下げる。Webサービスの急速な普及とクラウドコンピューティングの発展とともに広まり、Netflixなどの大規模サービスがモノリスからマイクロサービスへ移行した事例が注目を集めた。
Backend for Frontend 2010年代、スマートフォンの爆発的普及により、一つのシステムがWebブラウザ、iOS、Androidといった複数のOS、ブラウザに対応する必要に迫られた。当初は単一の汎用REST APIですべてを賄う「One Size Fits All」のアプローチが一般的であったが、モバイル端末における画面サイズの制約や不安定なネットワーク環境に対し、不要なデータの転送や多数の通信がパフォーマンスを著しく悪化させる要因となった。この課題への解として、2015年、SoundCloudのPhil CalçadoらがBFF (Backend for Frontend) パターンを提唱した。これは、各UIごとに専用のバックエンド層(APIゲートウェイの一種)を設けてマイクロサービス群へのリクエストを集約・最適化する設計であり、複雑化するバックエンドの論理を隠蔽しつつ、フロントエンドそれぞれのUX要件に特化したAPI提供を可能にするアーキテクチャとして定着した。
コンテナとKubernetes マイクロサービスの運用複雑性を解決するため、2013年、Dockerが登場。続いて2014年、Kubernetesが誕生した。これらにより、アプリケーションの「コンテナ化」と、それを統合管理する「オーケストレーション」は、モダンなシステム開発において不可欠な要素として定着した。この技術的進歩は、インフラストラクチャを一度構築したら変更しない「不変なもの(イミュータブル)」として扱い、すべてをコードで管理する Infrastructure as Code (IaC) の概念を確立させる契機となった。Kubernetesとその周辺ツールによるエコシステムにより、マイクロサービスアーキテクチャによる開発が一般的になった。
また、同じく2014年には AWS Lambda に代表される FaaS (Function as a Service) が登場し、サーバーレス・コンピューティングという新たなパラダイムが生まれた。これにより、開発者は基盤となるサーバーのプロビジョニングや管理業務から解放されることとなった。FaaSはイベント駆動型で関数が実行され、実働時間に対してのみ課金される従量課金モデルを採用しており、従来の常時稼働型サーバーと比較して高い経済合理性を実現すると同時に、負荷に応じて即座に拡張可能な柔軟なスケーラビリティを獲得した。
アーキテクチャの例 コンピュータソフトウェアのモジュール群を設計し、それらの間で通信を行う共通的な手法は数々存在する。以下に例をあげる。
クライアントサーバモデル 分散コンピューティング Peer to Peer パイプとフィルター プラグイン SSADM (モジュールベースだが、通常モノリシック) ソフトウェアコンポーネント (モジュールベース。オブジェクト指向プログラミング) サービス指向アーキテクチャ 三層モデル コアドメインの独立 ヘキサゴナルアーキテクチャ クリーンアーキテクチャRobert C. Martin. (2012). The Clean Architecture. UIの分離 Model-View-Controller/MVC: ドメイン・表示・入力の分離 Model-View-ViewModel/MVVM: 状態をもつModelと宣言的Viewの分離、view stateをもちModel↔Viewを仲介するVM マイクロサービスアーキテクチャ
関連項目 ソフトウェア工学 デザインパターン アンチパターン 標準データモデル エンタープライズアーキテクチャ システムアーキテクチャ
脚注
参考文献 Len Bass, Paul Clements, Rick Kazman: Software Architecture in Practice, Second Edition. Addison Wesley, Reading 5/9/2003 ISBN 0-321-15495-9 (現在は第二版。基本概念を詳述している。テーマは主に品質に関すること) Garzás, Javier, and Piattini, Mario. An ontology for micro-architectural design knowledge, IEEE Software Magazine, Volume: 22, Issue: 2, March-April 2005. pp. 28 – 33. Philippe Kruchten: Architectural Blueprints - the 4+1 View Model of Software Architecture. In: IEEE Software. 12 (6) November 1995, pp. 42-50 (オンライン版は Rational website(PDF))
外部リンク Software architecture definitions at Carnegie Mellon University Software Engineering Institute Software architecture vs. software design Worldwide Institute of Software Architects Grady Booch's Handbook of Software Architecture project SoftwareArchitectures.com この分野に関する独自の情報源 International Association of Software Architects Microsoft Architecture Journal