Architecture as Code と検証でソフトウェア劣化を防ぐ方法

このブログは「How to Stop Software Erosion: An Architecture as Code and Verification Approach」を翻訳・一部加筆したものです。

ソフトウェアアーキテクトとして、私たちは皆、最良の意図からスタートします。クリーンな構造、明確な責任分担、そして整然としたボックスと矢印で埋め尽くされた満足感のある図面。しかし…現実が襲ってきます。

納期が迫ります。機能要件が変更されます。チームメンバーが不在になります。誰かが重要な納期に間に合わせるため、ワークアラウンドをハードコーディングします。それは機能しますが、ドキュメントは更新されません。そうして、丁寧に設計されたアーキテクチャは徐々に劣化されていきます。

この劣化は、突然起こるものではありません。静かに、層ごとに、決定ごとに、徐々に進行します。

Qt World Summit での最近の講演で、私たちは重要な質問を投げかけました。

アーキテクチャの劣化がシステムを静かに破壊する前に、
それをどのように阻止するのでしょうか?

Axivionの専門家である Andreas Gaiser 博士と Daniel Simon 博士は、チームがアーキテクチャを日常のワークフローに組み込み、コードで積極的に適用できるように支援する作業に長年取り組んできました。この投稿では、セッションで取り上げた主要なアイデアと、アーキテクチャ検証を実践的な現実にする方法について解説します。

ボックスと矢印から始り…現実の壁にぶつかる

セッションは、おそらく誰もが経験したことがあるストーリーから始まりました。

CまたはC++で実装された小さなシステムの教科書的なアーキテクチャを想像してください。ハードウェア抽象化を最下層に、ミドルウェアを中間層に、QtベースのUIを最上層に配置した、すっきりとした3層設計です。すべてが完璧に分離されています。しかし現実が襲います。トレードショー用に明日までにプロトタイプが必要になりました。ミドルウェア開発者が病気で欠勤しています。そこで、誰かがUIを直接ハードウェアに接続します。
問題ありません 「デモ用だから」

しかし、そのジグザグの回避策はアーキテクチャ図には決して含まれません。アーキテクチャ仕様を更新する人もいません。「意図した内容」と「コードの内容」のギャップはますます大きくなります。これが侵食のはじまりです。最悪なのは、それが目に見えないことです。

アーキテクチャ検証が不可欠な理由

アーキテクチャの劣化は、悪いコードの問題ではありません。設計と実装の制御不能な乖離が原因です。必要なのは、その乖離を可視化する方法です。そこで静的解析が役立ちます。

アーキテクチャモデルを透明シートに置き、実際のコードの上に重ねるイメージです。接続が一致しない場合、問題の場所を正確に特定できます。

静的解析とアーキテクチャ検証により、次のようなことが可能です。

  • アーキテクチャ違反と隠れた依存関係を検出
  • 使用されていないコンポーネントと古いリンクを特定
  • CIでアーキテクチャを強制適用し、長期的な劣化を防止
  • コードベースで本当に何が起こっているかを理解

そして重要なのは、これらはコードを実行せずに機能することです。すべて静的です。

アーキテクチャ・アズ・コード (AoC) の実践的なアプローチ

ボックスと矢印は可視化のための優れたツールです(UML をその特殊なバリエーションと考えることができます)。しかし、大規模プロジェクトでは、一部のアーキテクトは別のスケーラブルなアプローチを好みます。すなわち、Architecture-as-Code

脆弱な図やプロプライエタリなモデリングツールは忘れましょう。代わりに、アーキテクチャモデルをクリーンで人間が読みやすい Python コードで記述します。はい、コードです。

このアプローチでは、

  • コンポーネントはクラスまたは宣言になります
  • 依存関係は、明確で読みやすいルールで定義されます
  • アクセス境界(例:パブリック vs. プライベートインターフェース)は明示的にモデル化されます

そして、モデルはコードベースと一緒に存在し、バージョン管理(例:Git)でバージョン管理され、IDEで編集でき、他のファイルと同様にレビューできます。

新しいUMLツールを学ぶ必要も、XMLベースのモデルを孤立して管理する必要もありません。Python DSLは、アーキテクチャをアクセス可能で強制可能なものにします。

アーキテクチャ検証の3つの要素

静的な図から強制可能なアーキテクチャに移行するには、3つの重要な要素が必要です:

  1. アーキテクチャモデル – コンポーネントとその許可された依存関係を構造化して定義したもの(例:Python DSL 経由)
  2. コードモデル – 静的解析によりソースから生成されたもの
  3. マッピング – コード要素(ファイル、ディレクトリ、関数)とそのアーキテクチャ上の役割を結びつけるリンク

この3つが揃わなければ、アーキテクチャの検証は推測に過ぎません。これらを組み合わせることで、違反、欠落、予期しない依存関係に関する正確で実行可能な洞察を得ることができます。これらの3つの要素は検証のためだけのものではありません。開発者と「コミュニケーション」を取るためにも同様に必要です。

このマッピングステップはよく見落とされますが、アーキテクチャを強制可能なものに変える重要な要素です。マッピングは、ファイルパス、ディレクトリ、さらには個々のクラスや関数によって定義できます。また、内部と公開アクセスポイントをモデル化するために、マッピングを洗練することもできます。

ソフトウェアアーキテクチャ検証で検出(および修正)できるもの

アーキテクチャモデル、コードモデル、およびマッピングが定義されたら、開発中または CI パイプラインでルールを自動的に強制することができます。

システムは、主に 3 つの状況をフラグで示します。

  • 収束:コードがアーキテクチャと一致しています。問題はありません
  • 乖離:コードがアーキテクチャの境界を違反しています(例:UI がハードウェアを直接呼び出す)
  • 欠落:アーキテクチャで定義されている依存関係がコードに存在しなくなっています

各ケースには異なる意味があります。乖離は修正が必要、または少なくとも議論が必要です。欠落は、アーキテクチャの陳腐化や未使用のコンポーネントを意味する可能性があります。

本リンクのセッションでは、実際の例を示しました。 内部ヘッダー経由でアクセスされるグローバル変数、中間層をバイパスする関数、静かに忍び込む依存関係。これらのすべてがグラフに表示され、マッピングによりソースコードに紐付けられました。

アーキテクチャは開発の生きている一部

私たちは、アーキテクチャは生きているアーティファクトであり、PowerPoint や忘れ去られた Confluence ページではないと考えています。アーキテクチャはリポジトリに存在し、チームとともに進化し、継続的に検証されるべきです。

すべてを事前にモデル化する必要はありません。小さなところから始めてください。基本的な高レベルモデルでも、特に誰が何を依存しているか誰も覚えていないレガシーシステムでは、実際の違反を検出できます。

以下のセッションでは、Dr. Daniel SimonとDr. Andreas GaiserがAxivionを使用したアーキテクチャ検証の実際の例を解説し、違反を早期に検出する方法、コードでアーキテクチャをモデル化する方法、システムが静かに方向から外れるのを防ぐ方法を具体的に示します。

セッションはこちらをご覧ください


Axivion が実現するメリット

アーキテクチャ DSL からコードマッピング、静的解析、違反レポートまで、ご紹介したすべての機能は、Axivion Suite でそのままご利用いただけます。

Axivion では、以下の機能が利用可能です。

  • クリーンな Python ベースの DSL によるアーキテクチャモデリング
  • コードからアーキテクチャへの自動マッピング
  • アーキテクチャ違反、コードの重複、侵食傾向を検出する静的解析
  • IDE と CI/CD パイプラインへの深い統合
  • 依存関係を探索し、問題をレビューし、意思決定をガイドするビジュアルツール

要約:アーキテクチャを可視化、強制可能、現実のものとして毎日活用できます。

実際の動作を確認

完全なセッションでは、実際の(意図的に複雑な)プロジェクトを例に解説します。トレードショーのデモ用のショートカットのような単純なソフトウェア劣化が、より深刻な違反に発展するプロセスを確認できます。そして、それが拡大する前に阻止する方法も学びます。

アーキテクチャが図面の中に存在すると仮定するのをやめましょう。アーキテクチャを本当に重要な場所、つまりコードベースに存在させましょう。


Blog Topics:

Comments