『アーキテクトの教科書』を読んで
はじめに
みなさん、こんにちは。
Groovesでエンジニアをやっているichikiと申します。(各種アカウントではryichkというIDを使っています)
『アーキテクトの教科書』という書籍を読了したのでそこで得た学びなどをまとめてみました。
👇こちらの書籍です。
目次や参考文献や索引などを除くと約240ページほどで、最初はサラッと読めそうだなと高を括っていたのですが、ソフトウェア・アーキテクチャやアーキテクティングというそもそもが幅広い領域を扱っている書籍ということもあり、幅広い知識が濃縮された濃い一冊だったと感じました。
ちなみに私がこの本を読もうと思った理由は、「アーキテクトって名前からして凄そうだけど一体何する人なんだろう?」「どうやったらなれるんだろう?」という疑問を持っていたからでした。
読了した今はだいぶアーキテクトやアーキテクティングに対する解像度が上がったように思います。
また、Forkwell Libraryでもこちらの書籍を取り上げており、こちらで著者の米久保 剛さんがお話しされていた内容も大変勉強になったので参考にさせていただきました。
第1章 アーキテクトの仕事
第1章は現代のソフトウェア開発を取り巻く環境の説明から始まって、アーキテクトの定義やアーキテクトに必要な資質などが書いてありました。
アーキテクトとは?
IPAがまとめた『ITスキル標準V3 2011』やIPAが管轄するシステムアーキテクト試験(SA)での説明を参考にすると、
アーキテクトは、ビジネス上の情報システム戦略を具体化するために必要な要件定義、設計、開発を行い、必要に応じて他の開発者の指導を行う人と私は理解しました。
大規模開発の場合、専任のアーキテクトを立てることが多いようですが、
小規模開発の場合では、テックリードや開発者がアーキテクトの役割を分担することが多いそうです。
テックリードとは?
テックリードという言葉が出てきましたが、テックリードとアーキテクトの違いは何でしょうか?
テックリードは、開発チームを率いて、ソフトウェア開発に関する技術的課題解決にあたる人のことを言うそうです。
テックリードには、ソフトウェア開発における豊富な専門的経験と技術に対する深い理解が必要ですし、それだけでなくチームをリードするための人柄や能力も必要です。
つまり、テックリードというのは、テクニカルスキル(技術力)とソフトスキルを使ってソフトウェア開発(チーム)をリードする役割のことを言います。
アーキテクトに必要な資質
著者が考えるアーキテクトが備えるべき能力や考え方を簡単にまとめると以下の6つになります。
- 設計力
- コーディング力
- 抽象化能力
- ビジネスの理解
- 好奇心
- 完璧主義よりも合理主義
第2章 ソフトウェア設計
第2章はソフトウェア開発プロセスの全体像から始まって、ソフトウェア設計の抽象レベルや設計原則などについて書かれていました。
ソフトウェア開発プロセス
ソフトウェア開発プロセスは、顧客の漠然としたニーズからスタートし、いくつかのフェーズを経て動作するソフトウェアへと仕上げていく一連のアクティビティから構成されます。
- 要求分析アクティビティ
- 設計アクティビティ
- 実装アクティビティ
- テストアクティビティ
アーキテクチャの設計は、設計アクティビティの一種です。
ソフトウェア設計の抽象レベル
ソフトウェアの設計では、抽象レベルを意識する必要があります。
この書籍では4つの抽象レベルに分けていました。
下に行くほど具体的になっていきます。
アーキテクチャ設計
アーキテクチャ設計は、最も抽象度が高い設計のことですね。
マイクロサービスアーキテクチャといったシステム全体の構造や、レイヤードアーキテクチャやクリーンアーキテクチャといったアプリケーションの基本構造などが該当します。
モジュール設計
モジュール設計は、システムを構成するモジュール構造を決める設計です。
モジュールは、ユースケースの実行に必要な機能を集めた構造のことです。
コンポーネント設計
コンポーネント設計は、コンポーネントをどのように構成し、それらを協調させるかを決める設計だそうです。
コンポーネントの定義はまちまちで文脈によっても異なるそうですが、この書籍では以下のような定義をしておりました。
コンポーネントとは、特定の振る舞いを提供する責務を持ち、明確なインターフェースにより定義されたソフトウェアの構成部品のこと。しばしば複数のクラスから成り立つ。
モジュールとコンポーネントの違い
コンポーネントは、単体でユーザーにとって意味のあるタスク(ユースケース)を実行できないが、モジュールは実行できる単位のことだそうです。
モジュールはコンポーネントの集合体によって成り立っています。
クラス設計
クラス設計は、プログラムの最小単位となる構成要素の設計のことです。
オブジェクト指向プログラミング言語ではクラスが該当し、関数型プログラミング言語では関数が該当します。
ソフトウェアの設計原則とプラクティス
ソフトウェアの設計は、構成要素への分割、各構成要素への責務の割り当て、構成要素同士の相互作用を決める行為です。
設計の良し悪しがソフトウェアの内部品質に影響し、悪い設計は技術的負債につながってしまいます。
良い設計を行なって技術的負債を回避するには、偉大な先人達が見出した設計原則やプラクティスを適切に使うことが有効です。
それぞれについて詳しく解説することはしませんが、書籍で紹介されていた設計原則とプラクティスについて列挙させていただきます。
SOLID原則
- SRP(単一責任の原則)
- OCP(オープン・クローズドの原則)
- LSP(リスコフの置換原則)
- ISP(インターフェース分離の原則)
- DIP(依存関係逆転の原則)
CLEANコード
- Cohensive(凝集性)
- Loosely Coupled(疎結合)
- Encapsulated(カプセル化)
- Assertive(断定的)
- Nonredundant(非冗長)
設計パターン
ソフトウェア設計におけるパターンとは、よく遭遇する設計上の問題に対する解決策や設計アプローチを再利用可能な形でまとめたもので、その代表例がGoFのデザインパターンです。
アーキテクチャレベルでの設計上の問題を解決するパターンには、アーキテクチャスタイルとアーキテクチャパターンがあります。
著者曰く、この2つの用語に厳密な一般定義はないそうなのですが、抽象度の違いによってこの2つを分けて理解しておいた方が良いそうです。
アーキテクチャスタイル
アーキテクチャスタイルは、ソフトウェアのソースコードの編成の仕方や相互作用についての「包括的な構造」と定義されているそうです。
全体的な方針を定めるコンセプトで、アーキテクチャパターンの上に位置する抽象度が高いものと考えると良いそうです。
書籍『ソフトウェアアーキテクチャの基礎 エンジニアリングに基づく体系的アプローチ』では、以下のアーキテクチャスタイルが紹介されているそうです。
分類 | アーキテクチャスタイル |
---|---|
モノリシック | レイヤードアーキテクチャ |
パイプラインアーキテクチャ | |
マイクロカーネルアーキテクチャ | |
分散 | サービスベースアーキテクチャ |
イベント駆動アーキテクチャ | |
スペースベースアーキテクチャ | |
サービス指向アーキテクチャ | |
マイクロサービスアーキテクチャ |
余談ですが、私はまだ読んでないので近いうちに読みたいなと思っています👇
アーキテクチャパターン
アーキテクチャパターンは、「特定の解決策を形成するのに役立つ低レベルの設計構造」と定義されているそうです。
アーキテクチャの方針を具体的なコードに落とし込んでいく際に活用するパターンです。
ソフトウェア設計の4つの抽象レベルでいうところのモジュール設計やコンポーネント設計などで活用できそうです。
第3章 アーキテクチャの設計
第3章はアーキテクチャの定義から始まって、アーキテクチャ設計の具体的な進め方について書かれていました。
アーキテクチャの定義
アーキテクチャは、ISO/ICE/IEEE 42010:2011では次のように定義されているそうです。
環境におけるシステムの基本的な概念や特性が、その要素や関係、および設計と進化の原則に具体化されたもの (著者訳)
上記の一文では少し理解しづらいので、著者はより具体的に説明してくださっています。
それによると、アーキテクチャは、ユーザーの課題を解決し価値を提供するという目的を持つシステムが備えるべき特性を具現化するためのものだそうです。
それに加えて、ソフトウェアをどのように設計してどう進化させていくかの根拠となる原理原則もひっくるめてアーキテクチャであるとしています。
さらに書籍では、アーキテクチャを次の4つの側面で捉えていました。
- アーキテクチャによって達成すべきこと (目的・コンセプト)
- ビジネス要求
- 機能
- 品質特性(-ility)
- 設計判断 (根拠)
- 比較評価マトリクス
- ADR
- システムの形状 (実現方法)
- アーキテクチャモデル
- 文書・規約・ガイドライン (実行指針)
- アーキテクチャ記述
- 開発規約
- (自動化された)チェック
アーキテクチャ設計のアクティビティ
アーキテクチャ設計のアクティビティとして以下の3つが示されていました。
- アーキテクチャドライバの特定
- アーキテクチャの選定
- アーキテクチャの文書化
アクティビティ | 主な作業内容 | 作成する成果物の例 |
---|---|---|
アーキテクチャドライバの特定 | 要求の分析、整理 | アーキテクチャドライバ一覧、品質特性シナリオ |
アーキテクチャの選定 | パータンを利用したアーキテクチャ検討、トレードオフ分析、比較評価 | アーキテクチャモデル、比較評価マトリクス、アーキテクチャプロトタイプ、ADR |
アーキテクチャの文書化 | アーキテクチャに関するドキュメント作成 | アーキテクチャ記述、各種規約、ガイドライン |
1. アーキテクチャドライバの特定
アーキテクチャドライバとは、アーキテクチャを検討する上で重要な考慮事項のことを言うそうです。
アーキテクチャドライバには、以下の4つの要素があるそうです。
- 制約
- 品質特性
- 影響を与える機能要求
- その他影響を及ぼすもの
制約
制約には、ビジネス上の制約と技術的な制約の2つがあります。
品質特性
ユーザーが求める機能要求を満たすことが最重要ですが、その上で重要視される品質特性(非機能要求)というものがあります。
ソフトウェアの品質を測定可能な特徴として定義したものを品質特性と呼ぶそうです。
品質特性は、顧客やユーザーのコンテキストやニーズによって決まります。
ソフトウェアの品質には、ユーザーが利用時に認識できる外部品質と、保守のしやすさのようにユーザーには見えない内部品質があります。
品質特性を整理分類した品質モデルとしてJIS X 25010(ISO/IEC 25010:2011)という規格があり、8つの品質特性とそれらが持つ品質副特性というものがあります。
出典:日本規格協会『日本産業規格JIS X 25010:2013(ISO/IEC 25010:2011)システム及びソフトウェア製品の品質要求及び評価(SQuaRE) - システム及びソフトウェア品質モデル』図4 - 製品品質モデル
こうやって見ると沢山の品質特性があって圧倒されてしまいそうですが、自分たちが採用するアーキテクチャにとって特に重要な品質特性を特定する必要があります。
上記8つの品質特性のうち、機能適合性は主にアプリケーションの機能として実現し、使用性に関してはUI/UXで実現することになるため、
アーキテクチャの観点では残り6つの品質特性(性能効率性、互換性、信頼性、セキュリティ、保守性、移植性)を中心に検討すれば良いと著者は仰ってました。
2. アーキテクチャの選定
特定したアーキテクチャドライバをもとに最適なアーキテクチャを選定します。
制約条件を満たしつつ品質特性を達成する方法を検討し、あるべきアーキテクチャの形を明らかにしていくフェーズです。
ここでのポイントは以下の2つだと著者は言います。
- アーキテクチャの選定はトレードオフであることを認識する
- パターンを活用する
システムアーキテクチャの検討
まずは、システム全体としてどのような構造を取るべきか、システムアーキテクチャの検討を行います。
最初の大きな判断は、モノリシックとするか分散アーキテクチャとするかです。
モノリシックアアーキテクチャと分散アーキテクトのメリット・デメリットを検討しつつ決断します。
分散アーキテクチャ構成の代表的パターン
分散アーキテクチャ構成の代表的パターンとしてサービスベースアーキテクチャとマイクロサービスアーキテクチャが挙げられていました。
サービスベースアーキテクチャという名前は初めて知ったのですが、システムを構成する複数のサービスが単一のデータベースを共有するモデルのことだそうです。
それに対して、マイクロサービスアーキテクチャは各サービスが専用のデータベースを持つモデルだそうです。
そのためトランザクション境界が複数のサービスをまたがる場合もあります。
ユーザーインターフェースから直接サービスを呼ぶのではなく、APIゲートウェイというAPIを集めたレイヤーを経由するケースも多いそうです。
アプリケーションアーキテクチャの検討
システムアーキテクチャの次は、アプリケーションアーキテクチャを検討します。
アプリケーションアーキテクチャの検討では、システムを構成する各サービスがどのようなアーキテクチャスタイルをとるべきかを検討します。
アプリケーションレベルのアーキテクチャスタイル
- レイヤードアーキテクチャ
- パイプラインアーキテクチャ
- マイクロカーネルアーキテクチャ
レイヤードアーキテクチャ
レイヤードアーキテクチャは、アプリケーションをいくつかのレイヤー(層)に分けたアーキテクチャスタイルです。
レイヤードアーキテクチャには欠点があり、その一つとして、抽象度が高く安定した上位モジュールであるドメイン層から、より詳細で不安定な下位モジュールであるデータアクセス層への依存が生じてしまうことが挙げられます。
ドメイン層のコードの見通しが悪くなるリスクや、データアクセス層で使用するライブラリのバージョンアップによってドメイン層のコード修正が発生するリスクなどが生じてしまいます。
この問題点を解決する方法として、依存関係逆転の原則(DIP)を適用したものが考え出され、それがオニオンアーキテクチャやヘキサゴナルアーキテクチャやクリーンアーキテクチャといったものだそうです。
しかし、これらのアーキテクチャにもデメリットはあり、設計難易度が上がったり、インターフェースやコンポーネントの数が増加して複雑度が増してしまうといったことがあるので注意が必要です。
これらは複雑なビジネスルールでもソースコードの見通しを良くするためのものなので、ビジネスルールが単純なアプリケーションに対しては採用しない方が無難そうです。
パイプラインアーキテクチャ
パイプとフィルター(Pipes and Filters)とも呼ばれるアーキテクチャスタイルで、次の図のような構造を持ちます。
フィルターは、パイプから受け取った入力データを逐次的に処理し、その結果を後続のパイプへ出力するコンポーネントです。
パイプはフィルター同士を繋ぐコンポーネントで、キューとしての役割を持ちます。
パイプラインアーキテクチャという名前は初めて聞いたのですが、代表例としてUnixシェル言語が挙げられると書いてあって、なるほどそういう名前が付いていたんだと思いました。
パイプラインアーキテクチャの活用例として、ビッグデータ分散処理基盤やAWS GlueのようなETLサービスなどがあるそうです。
一方向にデータが流れていって逐次的に処理を行なっていくシステムにおいて採用するのが良さそうです。
マイクロカーネルアーキテクチャ
マイクロカーネルアーキテクチャという名前も初めて聞いたのですが、これはアプリケーションの拡張性を高めるためのアーキテクチャで別名プラグインアーキテクチャとも言うそうです。
コアシステムとプラグインから構成され、コアシステムはシステムの核となる最小限の機能を持つコンポーネントで、顧客固有の要件に基づくカスタマイズにコアシステムが影響を受けないようにすることが主目的のアーキテクチャだそうです。
オープン・クローズド原則(OCP)を適用して拡張性を持たせ、多数のプラグインを拡張として使うことができるようにすることで多種多様な機能を実現することができます。
ただし、必要な拡張点の洗い出しやインターフェースの定義、既存プラグインに対する互換性の担保など、考慮すべき点があることに注意が必要とのことです。
アーキテクチャの比較評価
アーキテクチャ選定はトレードオフです。
全ての項目で満点を取れるような選択肢は存在しないので最もマシなものを選ぶ作業と言えます。
上位のビジネス要求も満たすための重要な考慮事項(アーキテクチャドライバ)を達成することがアーキテクチャの必要条件です。
比較評価マトリクスによるトレードオフ分析
比較評価マトリクスとは、アーキテクチャドライバやそれを分解した要素を評価軸として縦に取り、選択肢を横に並べたものです。
比較評価マトリクスは、複数の選択肢から有力な候補を絞り込むのに使うことができます。
アーキテクチャデシジョンレコード(ADR)
アーキテクチャデシジョンレコード(ADR)という手法があります。
これは、アーキテクトが行う大小様々な設計判断を他の開発者やステークホルダーに共有し、その判断が後工程で正しく実装に落とし込まれるようにするためのものです。
また、後にアーキテクチャの変更が必要となった際に現在のアーキテクチャがなぜ採用されたかが分かるようにするという目的もあります。
ADRは、1つの設計判断に対して1つのファイルをマークダウンなどの書式で作成するそうです。
3. アーキテクチャの文書化
ADRは個々の設計判断を記録する文書ですが、アーキテクチャ全体を説明する文書も作成する必要があり、それをアーキテクチャ記述(SAD: Software Architecture Description)と呼ぶそうです。
アーキテクチャ記述
ISO/IEC/IEEE 42010:2011はアーキテクチャ記述を標準化した規格で、
SEI(Software Engineering Institute)が公開するViews and Beyondというアーキテクチャ記述のテンプレートもあってダウンロードして使うことができるそうです。
アーキテクチャ記述には以下のような項目を含めるそうです。
- 目的
- 文書の目的や概要、対象読者、アーキテクチャの目的や目標など
- アーキテクチャドライバ
- 制約や品質特性、影響を与える機能要求
- システム全体構成
- アクターとステークホルダー
- ステークホルダーの例:プロダクトオーナー、アーキテクト、開発者、QAエンジニア、デザイナー、インフラエンジニア、セキュリティエンジニア、運用チーム、カスタマーサポートなど
- アーキテクチャモデル
- アーキテクチャの一側面を捉えてモデルとして表現した図やその説明
- アーキテクチャスタイルやアーキテクチャパターンを使ってアーキテクチャ構成を表した図など
ステークホルダーによって関心事は異なるのでアーキテクチャについて知りたい観点も異なります。
これらの関心事や観点に応じたアーキテクチャの捉え方や切り口のことをビューポイントと言い、それぞれのビューポイントについて実際にアーキテクチャをモデルとして表現した図をビューと言うそうです。
代表的なビューポイントセット(複数のビューポイントをまとめたフレームワーク)として、4+1ビューとC4モデルというものがあるそうです。
私は、C4モデルはどこかでちらっと聞いたことがある気がするのですが、4+1ビューというものは初めて知りました。
4+1ビュー
4+1ビューを用いたアーキテクチャモデリングでは、複数のビューポイントによって様々なステークホルダーの関心事を個別に扱うそうです。
4+1ビューの「4」は論理ビュー、開発ビュー、プロセスビュー、物理ビューの4つのことを指し、「+1」はシナリオビューを指すそうです。
C4モデル
C4モデルでは、システムを異なる4つの抽象レベルで捉え、それぞれに適したダイアグラムを使ってアーキテクチャをモデリングするそうです。
関心事を分離してソフトウェア開発におけるコミュニケーションを効果的にする狙いがあるそうです。
4つの抽象レベルとは、コンテキスト、コンテナ、コンポーネント、コードのことで、それぞれ特定の関心事を表すのに適したモデルを利用します。
第4章 アーキテクチャの実装
第4章は設計したアーキテクチャを実際に動作するソフトウェアとして実現するためにアーキテクトが主導で取り組むべき作業についても書かれていました。
アプリケーション基盤の構築
使用するプログラミング言語やソフトウェア製品、フレームワークやライブラリなどの技術は、アーキテクチャドライバに基づいてアーキテクトが選定を行います。
また、認証・認可やロギングなどをアプリケーション基盤として、アーキテクトが設計や実装を主導します。
例えば、アプリケーション基盤には以下のようなものがあると書かれていました。
- 認証
- 認可
- セッション管理
- エラーハンドリング
- ロギング
- セキュリティ
- トランザクション制御
- データベースアクセス
- 国際化
- 帳票出力
- キャッシュ管理
- 非同期処理
アプリケーション開発フローの構築
どのような手順で開発を進めるのか共通のルールを定義し、実際に開発を進める上で必要な環境やツールを整備することもアーキテクトの重要や役目として書かれていました。
第5章 品質保証とテスト
第5章には品質保証についてや機能テスト自動化やパフォーマンステストなどについて書かれていました。
詳細については省きますが、ぜひ書籍で確認してみてください😉
第6章 アーキテクトとしての学習と成長
第6章はアーキテクトの人物像から始まって、どうやって必要な知識やスキルを身につけていけば良いかや効果的な学習方法について書かれていました。また、著者のおすすめ書籍もいくつか紹介されていました。
アーキテクトとして成長するために
書籍には以下のようなことが書いてあり、アーキテクトとして活躍するために必要な知識やスキルは一朝一夕で身に付くものではないので日々の学習や積み重ねが本当に重要だと感じます。
アーキテクトはアーキテクティングを専門領域とするスペシャリストであると同時に、ソフトウェアエンジニアリング全般の知識や経験を有するジェネラリストであることが求められます。
- IT技術やソフトウェアエンジニアリングに関する幅広い知識や経験が必要
- アーキテクティングに関する手法を学び、実際の業務で経験を積んでいくことが必要
- 複数の技術領域での知識やスキルを磨き、得意分野を持っておくことも大切
- ビジネスの理解も必要
- ビジネス側の人々や様々なステークホルダーと協力して一緒に価値を創造していくためのコミュニケーションスキルやリーダーシップなども必要
『アーキテクトの教科書』の使い方
アーキテクトとして成長するためにこの書籍をどう使えば良いか、Forkwell Libraryにて著者の米久保さんは以下のような説明をされていました。
初学者
設計原則・パターンから品質保証まで幅広く学ぶために使う良い。
中級者以上
『アーキテクトの教科書』を全体感を整理して俯瞰するために使うと良い。
その後でより専門的な書籍で深掘りすると良い。
アーキテクチャの学び方
アーキテクチャスタイルやアーキテクチャパターンは書籍などで学ぶことができます。
しかし、一番重要なのは、実践で学んでいくことで経験知を得ることだと著者の米久保さんは言います。
私もそう思います。
プロダクト開発でアーキテクチャ設計を行う場合は、その状況で求められる品質特性や制約などを踏まえて、それに適用するようなアーキテクチャを考えて使う必要があります。
知識として持っていてもそれをうまく活用できなければ意味がありません。
しかし、最初からうまくいくことは難しいと思うのでやはり自らチャンスを掴みに行って経験を積むことが重要だと思いました。
とは言え、アーキテクチャ設計は規模も大きいしタイムボックスも比較的長いので沢山の経験を1人で次々としていくのはなかなか難しいので、他社の経験などを見聞きして学ぶことも有効な手段だと、米久保さんはForkwell Libraryにて仰っていました。
終わりに
だいぶ長くなってしまいましたが、もし最後まで読んでくださったとしたらありがとうございます🙏(途中まででもありがとうございます!)
とても幅広い内容を扱っている書籍なので、他にも記載したかった内容やもっと詳細に記載したかった内容もあるのですが、キリがなくなってしまうのでここまでにしました!
すでに沢山記載しましたが、もっと濃い内容がこの書籍には書かれているのでより詳細に知りたい方やアーキテクトに必要な知識やスキルを幅広く網羅的に学びたい方におすすめな一冊です!
Discussion