0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ソフトウェアアーキテクチャの基礎⑫ 第II部 アーキテクチャスタイル 第12章 マイクロカーネルアーキテクチャ

0
Posted at

はじめに

前章(第11章)では、Producer・Transformer・Tester・Consumerというフィルターを連結し、データフローを中心にシステムを構築するパイプラインアーキテクチャを学びました。

一方、本章で扱うマイクロカーネルアーキテクチャ(Microkernel Architecture)は、「システムをどう流すか」ではなく、「システムをどう拡張するか」に焦点を当てたアーキテクチャです。本書ではこのスタイルをプラグインアーキテクチャ(Plug-in Architecture)とも呼んでいます。

このアーキテクチャの最大の特徴は、コアシステムとプラグインという2つの要素による構造にあります。コアシステムはアプリケーションに共通する最小限の機能だけを持ち、製品ごとの差異や顧客ごとのカスタマイズはプラグインとして外部へ切り出します。共通機能をコアシステムが担い、顧客A向け機能はプラグインA・顧客B向け機能はプラグインBという形で分離します。

実は私たちは日常的にこのアーキテクチャを利用しています。Eclipse・IntelliJ IDEA・VS Code・Chrome・FirefoxといったIDEやブラウザは、マイクロカーネルアーキテクチャの代表例です。VS Codeを例にすると、本体にPython拡張・Docker拡張・GitHub Copilot拡張を追加していく形で、必要な機能だけを後から組み込めます。OSにおけるカーネルとデバイスドライバの関係も、マイクロカーネルの思想に近いものです。


本章では以下の問いに向き合います。

  • マイクロカーネルアーキテクチャとは何か
  • コアシステムとプラグインはどう分離するのか
  • プラグインはどのように管理するのか
  • なぜ高い拡張性を実現できるのか
  • どのようなシステムに向いているのか

第10章では「構造」を、第11章では「データフロー」を学びました。第12章では**「変化を受け入れる仕組み」**としてのアーキテクチャを学んでいきます。


📖ソフトウェアアーキテクチャの基礎

本書は、O’Reilly Media から出版された『Fundamentals of Software Architecture: An Engineering Approach』 の日本語版です。著者の Mark Richards と Neal Ford が、アーキテクチャを工学的視点から捉え直し、理論と実務を橋渡しする知見をまとめた一冊です。

https://www.oreilly.co.jp/books/9784873119823/

目次(全24章)

1章 イントロダクション 1.1 ソフトウェアアーキテクチャの定義
1.2 アーキテクトへの期待
1.2.1 アーキテクチャ決定を下す
1.2.2 アーキテクチャを継続的に分析する
1.2.3 最新のトレンドを把握し続ける
1.2.4 決定の順守を徹底する
1.2.5 さまざまなものに触れ、経験している
1.2.6 事業ドメインの知識を持っている
1.2.7 対人スキルを持ち合わせている
1.2.8 政治を理解し、かじ取りをする
1.3 アーキテクチャと交わるもの
1.3.1 エンジニアリングプラクティス
1.3.2 運用とDevOps
1.3.3 プロセス
1.3.4 データ
1.4 ソフトウェアアーキテクチャの法則

第I部 基礎

2章 アーキテクチャ思考 2.1 アーキテクチャと設計
2.2 技術的な幅
2.3 トレードオフを分析する
2.4 ビジネスドライバーを理解する
2.5 アーキテクティングとコーディングのバランスを取る
3章 モジュール性 3.1 定義
3.2 モジュール性の計測
3.2.1 凝集度
3.2.2 結合度
3.2.3 抽象度、不安定度、主系列からの距離
3.2.4 主系列からの距離
3.2.5 コナーセンス
3.2.6 結合度とコナーセンスのメトリクスを統合する
3.3 モジュールからコンポーネントへ
4章 アーキテクチャ特性 4.1 アーキテクチャ特性の(部分的な)リスト
4.1.1 アーキテクチャの運用特性
4.1.2 アーキテクチャの構造特性
4.1.3 アーキテクチャの横断的特性
4.2 トレードオフと少なくとも最悪でないアーキテクチャ
5章 アーキテクチャ特性を明らかにする 5.1 アーキテクチャ特性をドメインの関心事から捉える
5.2 要件からアーキテクチャ特性を抽出する
5.3 事例:シリコンサンドイッチ
5.3.1 明示的な特性
5.3.2 暗黙的な特性
6章 アーキテクチャ特性の計測と統制 6.1 アーキテクチャ特性の計測
6.1.1 運用面の計測
6.1.2 構造面の計測
6.1.3 プロセス面の計測
6.2 統制と適応度関数
6.2.1 アーキテクチャ特性の統制
6.2.2 適応度関数
7章 アーキテクチャ特性のスコープ 7.1 結合とコナーセンス
7.2 アーキテクチャ量子と粒度
7.2.1 事例:Going、Going、Gone
8章 コンポーネントベース思考 8.1 コンポーネントの分類
8.2 アーキテクトの役割
8.2.1 アーキテクチャの分割
8.2.2 事例:シリコンサンドイッチにおける分割
8.3 開発者の役割
8.4 コンポーネントを識別する流れ
8.4.1 初期コンポーネントを識別する
8.4.2 コンポーネントに要件を割り当てる
8.4.3 ロールや責務を分析する
8.4.4 アーキテクチャ特性を分析する
8.4.5 コンポーネントを再構成する
8.5 コンポーネントの粒度
8.6 コンポーネント設計
8.6.1 コンポーネントの発見
8.7 事例:「Going、Going、Gone」におけるコンポーネントの発見
8.8 アーキテクチャ量子再び:モノリシックアーキテクチャと分散アーキテクチャの選択

第II部 アーキテクチャスタイル

9章 基礎 9.1 基礎的なパターン
9.1.1 巨大な泥団子
9.1.2 ユニタリーアーキテクチャ
9.1.3 クライアント/サーバー
9.2 モノリシックアーキテクチャと分散アーキテクチャ
9.2.1 誤信1:ネットワークは信頼できる
9.2.2 誤信2:レイテンシーがゼロ
9.2.3 誤信3:帯域幅は無限
9.2.4 誤信4:ネットワークは安全
9.2.5 誤信5:トポロジーは決して変化しない
9.2.6 誤信6:管理者は一人だけ
9.2.7 誤信7:転送コストはゼロ
9.2.8 誤信8:ネットワークは均一
9.2.9 分散コンピューティングにおけるその他の考慮事項
10章 レイヤードアーキテクチャ 10.1 トポロジー
10.2 層の分離
10.3 レイヤーの追加
10.4 その他の考慮事項
10.5 このアーキテクチャスタイルを採用する理由
10.6 アーキテクチャ特性の評価
11章 パイプラインアーキテクチャ 11.1 トポロジー
11.1.1 パイプ
11.1.2 フィルター
11.2 事例
11.3 アーキテクチャ特性の評価
12章 マイクロカーネルアーキテクチャ 12.1 トポロジー
12.1.1 コアシステム
12.1.2 プラグインコンポーネント
12.2 レジストリ
12.3 コントラクト
12.4 事例とユースケース
12.5 アーキテクチャ特性の評価
13章 サービスベースアーキテクチャ 13.1 トポロジー
13.2 トポロジーの種類
13.3 サービスの設計と粒度
13.4 データベース分割
13.5 アーキテクチャ例
13.6 アーキテクチャ特性の評価
13.7 このアーキテクチャスタイルがふさわしいとき
14章 イベント駆動アーキテクチャ 14.1 トポロジー
14.2 ブローカー
14.3 メディエーター
14.4 非同期の能力
14.5 エラー処理
14.6 データロスの防止
14.7 ブロードキャスト能力
14.8 リクエスト・リプライ
14.9 リクエストベースとイベントベースの間を取る
14.10 ハイブリッドなイベント駆動アーキテクチャ
14.11 アーキテクチャ特性の評価
15章 スペースベースアーキテクチャ 15.1 一般的なトポロジー
15.1.1 処理ユニット
15.1.2 仮想ミドルウェア
15.1.3 データポンプ
15.1.4 データライター
15.1.5 データリーダー
15.2 データ衝突
15.3 クラウドとオンプレミス
15.4 レプリケーションキャッシュと分散キャッシュ
15.5 ニアキャッシュの考慮
15.6 実装例
15.6.1 コンサートチケット販売システム
15.6.2 オンラインオークションシステム
15.7 アーキテクチャ特性の評価
16章 オーケストレーション駆動サービス指向アーキテクチャ 16.1 歴史と哲学
16.2 トポロジー
16.3 分類
16.3.1 ビジネスサービス
16.3.2 エンタープライズサービス
16.3.3 アプリケーションサービス
16.3.4 インフラストラクチャサービス
16.3.5 オーケストレーションエンジン
16.3.6 メッセージフロー
16.4 再利用...と結合
16.5 アーキテクチャ特性の評価
17章 マイクロサービスアーキテクチャ 17.1 歴史
17.2 トポロジー
17.3 分散
17.4 境界づけられたコンテキスト
17.4.1 粒度
17.4.2 データ分離
17.5 API層
17.6 運用面での再利用
17.7 フロントエンド
17.8 通信
17.8.1 コレオグラフィとオーケストレーション
17.8.2 トランザクションとサーガ
17.9 アーキテクチャ特性の評価
17.10 参考文献
18章 適切なアーキテクチャスタイルを選ぶ 18.1 アーキテクチャにおけるトレンドの変遷
18.2 判断基準
18.3 モノリスの事例:シリコンサンドイッチ
18.3.1 モジュラーモノリス
18.3.2 マイクロカーネル
18.4 分散型のケーススタディ:Going、Going、Gone

第III部 テクニックとソフトスキル

19章 アーキテクチャ決定 19.1 アーキテクチャ決定に関するアンチパターン
19.1.1 資産防御アンチパターン
19.1.2 グラウンドホッグデーアンチパターン
19.1.3 メール駆動アーキテクチャアンチパターン
19.2 アーキテクチャ上重要なもの
19.3 アーキテクチャデシジョンレコード
19.3.1 基本構造
19.3.2 ADRを保存する
19.3.3 ドキュメントとしてのADR
19.3.4 標準のためにADRを用いる
19.3.5 事例
20章 アーキテクチャ上のリスクを分析する 20.1 リスクマトリックス
20.2 リスクアセスメント
20.3 リスクストーミング
20.3.1 特定
20.3.2 合意
20.3.3 軽減
20.4 ユーザーストーリーリスク分析
20.5 リスクストーミング例
20.5.1 可用性
20.5.2 弾力性
20.5.3 セキュリティ
21章 アーキテクチャの図解やプレゼンテーション 21.1 図解
21.1.1 ツール
21.1.2 標準ダイアグラム:UML、C4、ArchiMate
21.1.3 図解ガイドライン
21.2 プレゼンテーション
21.2.1 時間を操る
21.2.2 段階的な構築
21.2.3 インフォデッキとプレゼンテーション
21.2.4 スライドは物語の半分
21.2.5 不可視化
22章 効果的なチームにする 22.1 チーム境界
22.2 アーキテクトのパーソナリティ
22.2.1 コントロールフリーク
22.2.2 アームチェアアーキテクト
22.2.3 効果的なアーキテクト
22.3 どうやって管理する?
22.4 チームの警告サイン
22.5 チェックリストの活用
22.5.1 開発者のコード完成チェックリスト
22.5.2 ユニットテストと機能テストのためのチェックリスト
22.5.3 ソフトウェアリリースのためのチェックリスト
22.6 ガイダンスの提供
22.7 まとめ
23章 交渉とリーダーシップのスキル 23.1 交渉とファシリテーション
23.1.1 ビジネスステークホルダーとの交渉
23.1.2 他のアーキテクトとの交渉
23.1.3 開発者との交渉
23.2 リーダーとしてのソフトウェアアーキテクト
23.2.1 アーキテクチャの4つのC
23.2.2 プラグマティックでありながらもビジョナリーであること
23.2.3 手本を示してチームをリードする
23.3 開発チームに溶け込む
23.4 まとめ
24章 キャリアパスを開く 24.1 20分ルール
24.2 パーソナルレーダーの開発
24.2.1 ThoughtWorksテクノロジーレーダー
24.2.2 オープンソースのビジュアライゼーションビット
24.3 ソーシャルメディアの使用
24.4 別れの挨拶

付録A 自己評価のためのチェックリスト
参考文献
訳者あとがき
索引
関連書籍

12.1 トポロジー

マイクロカーネルアーキテクチャの最大の特徴は、「コアシステム」と「プラグインコンポーネント」を分離することにあります。本書では、このアーキテクチャはコアシステムとプラグインコンポーネントから構成されると説明されています。

コアシステムにはアプリケーション全体で共通となる機能を配置し、顧客ごとの違い・製品ごとの差異・特殊な業務ルールなどはプラグインへ切り出します。変わりにくい部分をコアシステムが担い、変わりやすい部分をプラグインが担うという分離です。

なぜこの構造が必要なのか

たとえばスマートフォン査定システムを考えてみます。iPhone・Galaxy・iPadなど端末固有の査定ルールを単純な実装で扱うと、条件分岐が連鎖するコードになりがちです。新しい端末が追加されるたびにコアコードの修正・再テスト・再デプロイが発生し、変更に弱い構造になります。

マイクロカーネルでは各端末の査定ロジックを独立したプラグインとして実装するため、新端末の追加は新プラグインの追加だけで済みます。コアシステムは変更されません。これがマイクロカーネル最大の価値です。
image.png

12.1.1 コアシステム

コアシステム(Core System)は、アプリケーションを成立させるために必要な最小限の機能を持つ部分です。本書では、コアシステムには「共通で安定した処理」を配置すると説明されています。

スマホ査定システムであれば、査定要求の受付・プラグインの検索・査定の実行・結果の返却という流れを管理しますが、iPhone固有の査定ルールやGalaxy固有の査定ルールは持ちません。それらはプラグイン側へ委譲します。変更頻度が高い機能をコアシステムに置いてしまうと、マイクロカーネルのメリットが失われます。

本書では、コアシステムの実装パターンとして以下の2種類が紹介されています。

レイヤード型コアシステムは、コアシステム内部をPresentation・Business・Persistenceに分割する形であり、第10章で学んだレイヤードアーキテクチャをコアシステム内部へ適用します。

モジュール型コアシステムは、顧客・注文・決済・在庫といったドメイン単位で分割する形であり、第8章で学んだコンポーネント分割に近い考え方です。近年ではドメイン変更を局所化しやすいモジュール型が多い傾向があります。

image.png


12.1.2 プラグインコンポーネント

プラグインコンポーネントは、コアシステムを拡張するための独立したコンポーネントです。本書では、理想的なプラグインは独立・低結合・高凝集であるべきと説明されています。他のプラグインを知らず、コアシステムとも最低限の契約だけで接続します。

VS Codeであれば、本体にPython Extension・Docker Extension・GitHub Copilotが独立して追加される構造がその典型です。Python Extensionが壊れてもDocker Extensionには影響しません。

本書では、プラグインとコアシステムの通信は通常ポイントツーポイントで行われると説明されています。プラグイン同士が直接通信することは推奨されません。プラグイン間に直接の依存関係が生まれると結合度が増加し、第3章で学んだコナーセンスの問題に直結するためです。

UIの配置については本書で複数のパターンが紹介されています。UIがコアシステムを通してプラグインへアクセスする単一デプロイ型・プラグインが独立してUIを持たない形・プラグインごとにUIを持つ形があり、どれを採用するかはシステムの特性によります。

12.1 まとめ

マイクロカーネルアーキテクチャとは、「変化する部分」と「安定した部分」を明確に分離するアーキテクチャです。コアシステムが安定性を担保し、プラグインが変化を吸収するという役割分担によって高い拡張性を実現しています。

  • コアシステムには共通で安定した機能を配置する
  • プラグインには変化しやすい機能を配置する
  • コアシステムにはレイヤード型とモジュール型の実装パターンがある
  • プラグインは独立・低結合・高凝集であることが理想である
  • プラグイン同士の直接通信は避け、コアシステムを介した通信を基本とする

12.2 レジストリ

前節では、コアシステムとプラグインコンポーネントというマイクロカーネルアーキテクチャの基本構造を学びました。ここで新たな疑問が生まれます。プラグインが増えたとき、コアシステムはどうやって目的のプラグインを見つけるのでしょうか。

iPhone査定・Galaxy査定・iPad査定・Pixel査定など、数十から数百のプラグインが存在する場合、コアシステムが個別の実装を直接知っているわけにはいきません。そこで登場するのがレジストリ(Registry)です。

レジストリとは何か

本書では、レジストリはプラグイン名と実装情報を管理する仕組みとして説明されています。いわば電話帳のような存在であり、iPhoneにはiPhonePlugin・GalaxyにはGalaxyPlugin・iPadにはiPadPluginという対応表を持ちます。コアシステムはこの対応表を利用して必要なプラグインを探します。

なぜ必要なのか

レジストリが存在しなければ、コアシステムはデバイスの種類ごとに条件分岐でプラグインを生成するコードを持つことになります。新しいプラグインが追加されるたびにコアシステムを修正する必要があり、「プラグイン追加=コア変更」という状況が生まれます。これはマイクロカーネルアーキテクチャが避けようとしていることそのものです。

レジストリを導入することで、新しいプラグインはレジストリへの登録だけで追加できるようになります。コアシステムは変更されません。


レジストリの役割

レジストリの主な責務は以下の3つです。

  • プラグイン探索として、コアシステムは査定対象のキー(例:Galaxy)を渡すだけで、対応するGalaxyPluginをレジストリが返します。

  • プラグイン管理として、現在利用可能なプラグインの登録・更新・削除を一元的に管理します。

  • プラグイン切替として、旧査定ロジックから新査定ロジックへの変更が必要な場合、コアシステムを変更せずレジストリの設定だけを更新することで対応できます。


実装パターン

本書では、レジストリの実装方法はいくつか存在すると説明されています。

最もシンプルな方法は内部レジストリとしてHashMapのようなデータ構造で管理する方法であり、プラグイン数が少ない場合に向いています。

構成ファイル(plugins.xml・plugins.json・plugins.yaml)に定義する方法は運用しやすく、再コンパイル不要でプラグインを追加できます。

大規模システムではデータベース管理によって動的なプラグイン管理を実現する場合もあります。

本書ではメッセージングシステムの例も示されています。iPhone向けのキュー・Galaxy向けのキューというようにプラグインごとの接続情報をレジストリが保持し、コアシステムはキーとなるデバイス名だけを知っていれば実際の接続先はレジストリが解決します。


レジストリがもたらす効果

レジストリの導入により、コアシステムはプラグインの具体的な実装を知る必要がなくなります。知る必要があるのはインターフェースとしての契約だけです。第3章で学んだ結合度を下げ、第7章で学んだコナーセンスも弱めることができます。特に名前レベルのコナーセンス程度で済み、実装の変更が局所化されます。

12.2 まとめ

レジストリとは、**「コアシステムがプラグインの存在を直接意識しなくて済む仕組み」**です。コアシステムは「何を実行するか」だけを知り、レジストリは「どのプラグインを実行するか」を解決します。この役割分離がマイクロカーネルアーキテクチャの高い拡張性を支えています。

  • レジストリはプラグインの探索・管理・切替を担う管理機構である
  • プラグインの追加はレジストリへの登録だけで完結し、コアシステムの変更が不要になる
  • 実装パターンには内部レジストリ・構成ファイル・データベース管理がある
  • コアシステムとプラグイン間の結合度とコナーセンスを低減できる

12.3 コントラクト

前節では、コアシステム・プラグインコンポーネント・レジストリというマイクロカーネルアーキテクチャの主要要素を学びました。ここで新たな疑問が生まれます。コアシステムとプラグインはどのように連携するのでしょうか。

コアシステムがプラグインの内部実装を直接知ってしまうと強い依存関係が生まれ、プラグイン変更のたびにコアシステムも修正が必要になります。これはマイクロカーネルアーキテクチャが目指す「独立した拡張性」に反します。そこで登場するのがコントラクト(Contract)です。


コントラクトとは何か

本書では、コントラクトをプラグインが守るべき約束事として説明しています。コアシステムはプラグインの実装内容を知らず、代わりに「このメソッドを持つこと」「このデータ形式を返すこと」だけを要求します。コアシステムが知るのは実装ではなく契約です。

スマホ査定システムを例にすると、コアシステムはiPhonePluginやGalaxyPluginを直接知りたくありません。知る必要があるのは「査定できること」だけです。そこで本書では以下のような共通インターフェースが示されています。

public interface AssessmentPlugin {
    public AssessmentOutput assess();
    public String register();
    public String deregister();
}

コアシステムは plugin.assess() を呼び出すだけで、それがiPhone査定なのかGalaxy査定なのかを知りません。


入力コントラクトと出力コントラクト

本書では、コントラクトには入力と出力の2種類があると説明されています。

入力コントラクトはプラグインが受け取るデータ形式です。たとえば {"device":"iPhone", "storage":128, "condition":"A"} という査定依頼がこれに該当します。

出力コントラクトはプラグインが返すデータ形式です。本書ではAssessmentOutputの例が示されています。

public class AssessmentOutput {
    public String assessmentReport;
    public Boolean resell;
    public Double value;
    public Double resellPrice;
}

どの査定プラグインもこの形式で結果を返すため、コアシステムは結果の扱い方を統一できます。iPhone査定ロジックがAI判定へ変わっても、Galaxy査定がルールベースのままであっても、コアシステムは影響を受けません。


第3章とのつながり

コントラクトは第3章で学んだコナーセンスとも直結します。コアシステムとプラグインが同じ内部ロジックを共有している場合、アルゴリズムのコナーセンスや実行順序のコナーセンスが発生します。しかし契約だけを共有する場合は、名前と型程度の静的コナーセンスに抑えられます。これは第7章で学んだ疎結合設計そのものです。

VS Codeを例にすると、Python Extension・Docker Extension・GitHub CopilotはVS Code本体と一定の契約を共有しています。しかし各拡張機能の内部実装をVS Code本体は知りません。だからこそ数千ものプラグインを追加できるのです。


コントラクトのメリット

コントラクトの導入によって、コアとプラグインが実装を共有せず契約を介してのみ接続されるため疎結合を実現できます。新しいプラグインを追加する際もコアシステムの変更が不要であり、モック実装によるテストもしやすくなります。内部実装の変更は各プラグイン内に局所化されるため保守性も高まります。


12.3 まとめ コアシステムとプラグインは、実装を共有するのではなく**契約(コントラクト)を共有します**。コアシステムは「何をするか」を知り、プラグインは「どう実現するか」を担当する。この分離がマイクロカーネルアーキテクチャの高い拡張性と保守性を実現しています。
  • コントラクトはコアシステムとプラグイン間の共有された契約である
  • コアシステムはプラグインの実装を知らず、インターフェースとデータ形式のみを知る
  • 入力コントラクトと出力コントラクトの2種類がある
  • コントラクトにより実装レベルのコナーセンスを静的コナーセンスに抑えられる
  • 実装変更の影響がプラグイン内に局所化され、拡張・保守がしやすくなる

12.4 事例とユースケース

ここまで、コアシステム・プラグインコンポーネント・レジストリ・コントラクトというマイクロカーネルアーキテクチャの主要要素を見てきました。では実際にはどのようなシステムで利用されるのでしょうか。

本書では、マイクロカーネルアーキテクチャは**「基本機能は共通だが、一部だけが顧客や業務によって変化するシステム」**に適していると説明されています。共通部分が大半を占め、カスタマイズが必要な部分が一定の割合で存在するシステムがその典型です。


保険金請求処理システム

本書で詳しく紹介されているのが、保険会社向けの保険金請求処理システムです。請求受付・内容確認・査定・支払い判定・支払いという業務フローは、どの保険商品でもほぼ共通です。しかし査定ルールは保険商品ごとに異なります。自動車保険では事故種別・修理費用・過失割合を考慮し、医療保険では診断書・入院日数・手術内容を考慮します。業務フローは同じで、判定ルールだけが異なるという構造です。

レイヤードアーキテクチャで実装した場合、Business LayerにすべてのルールがClaimServiceとして集約されます。新商品が追加されるたびにコアコードの修正・全体テスト・再デプロイが必要となり、第9章で学んだ巨大な泥団子へ向かう典型的なパターンです。

マイクロカーネルで実装した場合、査定ルールをプラグインとして分離します。保険金請求コアに対し、自動車保険Plugin・医療保険Plugin・火災保険Plugin・旅行保険Pluginを接続する構造です。新商品としてペット保険を追加したい場合はペット保険Pluginを追加するだけで済み、コアシステムは変更されません。

ここで重要なのは、業務フロー自体は安定しているという点です。変わるのは査定ルールだけであり、安定部分をコアに・変化部分をプラグインにという、マイクロカーネルの理想形が成立しています。


フォーム入力システム

本書では、企業ごとに異なる申請フォームを扱うシステムも紹介されています。入力・検証・保存という処理フローはどのフォームでも共通ですが、フォームごとに入力項目が異なります。Form1001では氏名・住所・電話番号、Form1040では所得・控除・税額、Form2000では契約情報・署名というように、フォームによって内容は大きく変わります。

すべてのフォームを一つのアプリに埋め込むと巨大な条件分岐になります。マイクロカーネルでは各フォームを独立したプラグインとして実装し、Form Coreに対してForm1001 Plugin・Form1040 Plugin・Form2000 Pluginを接続する構造にします。新しいフォームが追加されてもコアは変更されません。


IDEとブラウザ

私たちが日常的に使うソフトウェアもマイクロカーネルアーキテクチャの代表例です。VS Codeはコード編集機能をコアとして持ち、Python Extension・Docker Extension・Git Extension・Copilot Extensionといった追加機能をプラグインとして提供します。ChromeはAdBlock・Password Manager・Translator・Dark Readerなどの拡張機能をブラウザ本体を変更せずに追加できます。


どのようなシステムに向いているのか

マイクロカーネルアーキテクチャが向くのは、製品ラインナップが多く顧客ごとの違いが大きいシステム・機能追加の頻度が高くカスタマイズが多いシステム・コアとなる共通基盤が安定しているシステム・SaaSにおけるテナントごとの機能差がある場合などです。

逆に、コアシステム自体が頻繁に変わるシステムには向きません。コアが不安定になるとマイクロカーネルのメリットが失われます。


12.4 まとめ

マイクロカーネルアーキテクチャは**「変化するルールをプラグインへ隔離するアーキテクチャ」**です。安定した業務フローと変化する業務ルールという構造に非常に強く、レイヤードアーキテクチャやパイプラインアーキテクチャとは異なるマイクロカーネル独自の価値といえます。

  • 共通業務フローはコアシステムへ、商品ごとの査定ルールはプラグインへ配置する
  • フォーム入力システムやIDEやブラウザが代表的なユースケースである
  • カスタマイズが多く共通基盤が安定しているシステムに特に適している
  • 「安定部分」と「変化部分」を明確に分離することが成功の鍵である

12.5 アーキテクチャ特性の評価

ここまで見てきたように、マイクロカーネルアーキテクチャはコアシステムとプラグインコンポーネントという構造によって高い拡張性を実現します。本節では、アーキテクチャ特性の観点からその強みと弱みを整理します。

アーキテクチャ特性 評価
全体的なコスト ★★★★★
シンプルさ ★★★★
テスト容易性 ★★★★★
デプロイ容易性 ★★★
モジュール性 ★★★★★
信頼性 ★★★★
パフォーマンス ★★★
進化性 ★★★★
スケーラビリティ ★★
耐障害性 ★★
弾力性 ★★

モジュール性 ★★★★★

本書で最も高く評価されている特性の一つです。プラグインは独立・低結合・高凝集になるよう設計されます。iPhone査定・Galaxy査定・iPad査定の各プラグインは互いを知らず、コアシステムとはコントラクトだけを共有します。第3章で学んだ高凝集・低結合を実現しやすい構造です。


テスト容易性 ★★★★★

プラグイン単位でテストできるため非常に高い評価です。たとえばMedicalInsurancePluginだけを単独でテストでき、コアシステム全体を起動する必要はありません。コントラクトが明確なためモック実装も容易であり、テスト用の実装を作りやすい構造です。


全体的なコスト ★★★★★

通常は単一アプリ・単一デプロイとして構築されるため高い評価です。第9章で見たようなService Discovery・API Gateway・分散トレーシングといった仕組みが不要であり、運用コストを抑えられます。


シンプルさ ★★★★

レイヤードアーキテクチャほど単純ではありませんが、比較的理解しやすい構造です。基本的にはCore・Contract・Pluginという関係だけを理解すれば良い一方で、レジストリやプラグイン管理の仕組みが加わるためレイヤードより複雑になります。


信頼性 ★★★★

プラグインの障害がコアシステム全体へ波及しにくい点が評価されています。旅行保険Pluginが失敗しても自動車保険Pluginには影響しません。障害の影響範囲を局所化できる構造です。


進化性 ★★★★

マイクロカーネル最大の強みの一つです。新しい保険商品を追加する場合、新Pluginを追加するだけで済みます。コアシステムを変更せずに新機能を追加できる構造は、第5章で学んだ進化性に非常に優れています。


デプロイ容易性 ★★★

評価は中程度です。プラグインだけを差し替えられる場合もあれば、全体の再デプロイが必要な場合もあり、実装方式によって差があります。動的ロードができる環境では評価が上がります。


パフォーマンス ★★★

コアシステムからプラグイン呼び出しが発生するため多少のオーバーヘッドがありますが、分散システムのようなネットワーク通信は通常発生しないため、極端に低い評価にはなりません。


スケーラビリティ ★★・耐障害性 ★★・弾力性 ★★

これらはいずれも低評価です。通常は単一プロセスとして動作するため、査定Pluginだけが高負荷な場合でもシステム全体をスケールする必要があります。コアシステムが停止すると全プラグインが利用できなくなるため単一障害点になりやすく、Plugin単位での柔軟なスケールも得意ではありません。


第10章・第11章との比較

ここまで学んだアーキテクチャを比較すると、レイヤードアーキテクチャはシンプルさに強く変更の局所化が弱点、パイプラインアーキテクチャはデータフロー処理に強くスケーラビリティが弱点、マイクロカーネルアーキテクチャは拡張性に強くスケーラビリティが弱点という特徴があります。

マイクロカーネルアーキテクチャは「スケールのためのアーキテクチャ」ではなく、**「拡張のためのアーキテクチャ」**です。変更隔離・拡張性・モジュール性に強みを持つ一方、大規模分散・高スケール・高弾力性は得意ではありません。

12.4 まとめ
  • モジュール性・テスト容易性・全体コストは最高レベルの評価である
  • 進化性と信頼性も高く、拡張性を重視するシステムに最適である
  • 単一デプロイ構成のため運用コストが低い
  • コアシステムが単一障害点になりやすく、スケーラビリティ・耐障害性・弾力性は低い
  • マイクロカーネルは「スケールのためのアーキテクチャ」ではなく「拡張のためのアーキテクチャ」である

まとめ

第12章では「マイクロカーネルアーキテクチャ」について学びました。システムをコアシステムとプラグインコンポーネントとして構成し、変化しにくい部分と変化しやすい部分を明確に分離するアーキテクチャです。

  • コアシステムとプラグイン

本章ではまず、コアシステムとプラグインコンポーネントという基本構造を整理しました。コアシステムには共通で安定した機能を配置し、顧客固有機能・商品固有ルール・カスタマイズ機能はプラグインとして分離します。変更頻度が高い部分をシステムの外側へ切り出すこの考え方は、第5章で学んだアーキテクチャ特性の抽出にも通じています。

  • レジストリ

コアシステムとプラグインを仲介するレジストリについて学びました。レジストリはプラグイン名と実装情報を管理する仕組みであり、コアシステムは「何を実行したいか」だけを知り、どのプラグインを利用するかはレジストリが解決します。これによりプラグインを追加してもコアシステムの変更が不要になります。

  • コントラクト

本章で特に重要だったのがコントラクト(Contract)です。コアシステムとプラグインは実装を共有するのではなく、インターフェースとしての契約を共有します。AssessmentPluginのようなインターフェースをすべてのプラグインが守ることで、実装の変更が各プラグイン内に局所化されます。これは第3章で学んだ結合度・凝集度と、第7章で学んだコナーセンスを弱めるための重要な仕組みです。

  • ユースケース

本書では保険金請求システムとフォーム入力システムが代表例として紹介されています。いずれも業務フローは共通で業務ルールだけが個別に異なるという構造を持ちます。業務の流れは安定しているが一部のルールだけが変化するシステムにおいて、マイクロカーネルアーキテクチャは特に効果を発揮します。VS Code・IntelliJ IDEA・Eclipse・Chrome・Firefoxも、私たちが日常的に利用する代表的な実例です。

  • アーキテクチャ特性

モジュール性・テスト容易性・進化性に特に優れており、スケーラビリティ・弾力性・耐障害性はやや苦手です。マイクロカーネルアーキテクチャは「拡張のためのアーキテクチャ」であり、「スケールのためのアーキテクチャ」ではないということです。


本章の核心

第12章を通じて本書が伝えるのは、「変化する部分を隔離せよ」という考え方です。変更が頻繁に発生する機能をコアシステムへ埋め込むのではなくプラグインとして独立させ、コア・契約・プラグインという関係を維持することで高い拡張性を実現します。これは本書全体を通じて繰り返し登場する「変更を局所化する」というテーマの一つの到達点といえます。

終わりに

第10章ではレイヤードアーキテクチャを通じて「責務の分離」を、第11章ではパイプラインアーキテクチャを通じて「処理の流れの分離」を、そして第12章ではマイクロカーネルアーキテクチャを通じて「変化の分離」を学びました。責務を分離する・処理を分離する・変化を分離するという流れで、アーキテクチャの視点が発展してきました。

実際のシステム開発では、ほとんど変わらない部分と頻繁に変わる部分が存在します。優れたアーキテクチャとはその違いを見極め、変更の影響を最小化できる構造を作ることです。マイクロカーネルアーキテクチャはそのための強力な選択肢の一つです。

良いマイクロカーネルアーキテクチャとは、変化する部分をプラグインへ隔離し、安定したコアを守り続けられるアーキテクチャです。

次章(第13章)では「サービスベースアーキテクチャ(Service-Based Architecture)」を扱います。モノリシックアーキテクチャと分散アーキテクチャの中間に位置するこのスタイルでは、マイクロサービスへ至る前段階としてのサービス分割の考え方を学んでいきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?