2007年2月10日土曜日

ソフトウェアアーキテクチャ その9 - アーキテクチャ設計の実際 [arch]

これまで8回に渡って,ソフトウェアアーキテクチャの基本コンセプトを説明し,前回はその集大成としてケーススタディを紹介した.これからは,それらのコンセプトを実際にどう使うかというフェーズに入っていきたいと思う.

今回は実際に「アーキテクトのガイダンス」になるような設計の進め方について,紹介できればと思う.

Reference:
Software Architecture in Practice, Second Edition,
by Len Bass, Paul Clements, and Rick Kazman, Addison-Wesley 2003

--> Chapter 7

価格

Software Architecture in Practice (Sei Series in Software En
ソフトウェアの方式設計について実践を目的に、丁寧な解説を行っており、我が国のソフトウェア技術者が必...
あまなつShopあまなつで見る同じレイアウトで作成
アーキテクトのバイブルとされる本.SWEBOK (Software Engineering Body of Knowledge) でも推奨書籍とされている.

タイトルの "in Practice" (実践における) が示す通り,様々なケーススタディを交えつつ,非常に具体性のある内容になっている.


こちらがその和訳本.



本書第7章では,
- ライフサイクルにおけるアーキテクチャ
- アーキテクチャ設計
- チーム構成と,組織がアーキテクチャに及ぼす影響
- スケルタルシステムの構築
を扱っている.
それぞれに非常に興味深い内容だが,今回はライフサイクルについて軽く触れた後,ADD というアーキテクチャ設計手法を簡単に紹介したいと思う.


開発におけるライフサイクルについては,big-ban (waterfall) や cyclic という言葉で語られることが多いが,本書ではアーキテクチャを中心に考えた "Evolutionary Delivery Life Cycle" というモデルを定義している.
http://users.atw.hu/softarchpract/ch07lev1sec1.html

このライフサイクルモデルでは,設計は "Preliminary Requirements Analysis" (要求の予備分析) を伴う反復的なものだとしている.なにかしらのシステム要求が存在しない限り設計は始められないが,設計を始めるにあたって全ての要求が明確になっている必要はない.

まず最も重要なビジネスゴールを特定し,それらを品質特性シナリオ,もしくはユースケースに変換する.さらにこのリストからアーキテクチャに大きな影響を持つものを抽出する.

この抽出されたものが Architectural Drivers (アーキテクチャ決定要因) となる.そしてその数は10個未満にするべきだと述べられている.個人的にはシステム規模に関わらず「10個未満」と数を限定することに賛同はしかねるが,いずれにしても設計の初期段階でアーキテクチャ的に重要な要件を抽出することは必要だろう.

ちなみに本書の第11章では,"utility tree" というものを使って,ビジネス目標を品質特性シナリオに変換しているので,参考にしてもよいかもしれない.

Architectural Drivers が判明した時点で,設計は開始できる.もちろん設計の過程で生じた懸念事項が,要求分析に影響を及ぼすことはあり,それがこのモデルの反対向きの矢印が示すところだ.


では実際の設計を見てみよう.

本書第7章の大半は,今回のメインテーマである「アーキテクチャ設計」について,「品質特性駆動型設計」(ADD: Attribute Driven Design) という設計手法の解説に費やされている.

ADD は,RUP (Rational Unified Process) に代表されるその他の設計手法の拡張と位置付けられ,品質特性と機能要件の両者を満たす手法として知られている.

ADD は,Architectural Drivers をインプットとして扱い (特に品質特性は,システムに特化したシナリオとして書かれている必要がある),品質特性を基にモジュール分割を再帰的に行う.各段階で,一連の品質シナリオを満足する tactics と pattern を選択し,次に pattern によって提供されるモジュールタイプに機能責務を割り当ててインスタンス化する.

ADD のアウトプットは,モジュール分割 view の初期段階のレベル,そしてそれに対応したその他の view である.全ての詳細が ADD によってもたらされる訳ではなく,必然的に粒度も粗くなるが,これは設計プロセスにおける最初の明確なアーキテクチャの表現であり,機能要件を実現する為のフレームワークを提供する.

以下に ADD の各ステップを示す.

1. 分割するモジュールの選定
全てのモジュールは,「システム」「サブシステム」「サブモジュール」であると言える.モジュール分割は全体システムから始められ,そこからサブシステム,サブモジュールへと,細かい要素に分割されていく.

2. 選定されたモジュールの詳細化
a) Architectural Drivers の選択
システムに特化した品質特性シナリオと機能要件から,アーキテクチャの方針を決定する Architectural Drivers を選択する.つまりこの分割における重要事項の特定を行うことになる.これらは要件の優先順位の高いものから見つけることができる.トップダウンのアプローチだけではなく,例えばプロトタイプを構築し,その検証の過程で見つけることもあるだろう (特に performance など).

b) Architectural pattern の選択
Architectural Drivers を満たす pattern を選択する.この選択は,要求を満たすのに利用可能な tactics が基となる.本シリーズ「その5」で述べたように,tactics は特定の品質特性を促進するが,pattern に tactics が実装されると他の品質特性に対する影響 (多くの場合はトレードオフ) も発生する為,この点も考慮する必要がある.この時に,tactics を実装するサブモジュールも特定しておく.

c) モジュールのインスタンス化と責務割り当て
選択された pattern から,システムに特化する形でモジュールをインスタンス化する.さらに,そこにユースケースから機能要件を割りあてる.この過程で,サブモジュールを追加したり削除したりすることもあるだろう.この作業の結果,必然的に「情報交換の必要性」が明確になってくる為,次のステップではインターフェースの定義をすることになるが,その前にここでのアウトプットは,複数の view を使って表現しておくことが重要だ.

d) サブモジュールのインターフェース定義
モジュール分割は,モジュール,及びモジュールの相互作用関係に制約をもたらす.少なくとも設計の初期段階においては,「どんなサービスや知識を必要としているか,与えるか」を認識する.各モジュールごとに,この情報をインターフェース仕様書に記述する.ステップ c) で複数の view を記述したが,例えば module viewtype では producers-consumers の情報やモジュールが提供する必要があるインタラクションの種類を,concurrency view ではモジュール間のスレッドの相互作用やコンポーネントが active component (自分でスレッドを持つコンポーネント) かどうか,同期型か,シーケンスを持つのかブロックコールを使うのかといった情報を,deployment view ではハードウェアの要求やタイミング要求,通信要求などを記述することになる.

e) ユースケースと品質特性シナリオの検証,詳細化
ここまでのステップを通して,対象としていた機能要件と品質特性シナリオが満たされているかの検証を行い,必要に応じて要件の詳細化を行い,そしてそれらをサブモジュールの制約条件とする.このステップは,重要案件が抜けていないかを確認するだけではなく,サブモジュールを更なる詳細化に落とし込む,あるいは実装する為の準備段階となる.

3. 上記ステップを,分割が必要な全てのモジュールに対して繰り返す

これだけではピンとこないかもしれないが,今回は ADD の雰囲気だけでも伝わればと思い,各ステップの紹介に留めるが,本書では各ステップについて詳細な解説がされているばかりか,「ガレージ扉開閉機の設計」という例題を使って実際に ADD を実施している.

さらにこの章の後半では,この次の段階としてのチームビルディングや,設計を反映したチーム構成の重要性,組織がアーキテクチャに与える影響,またさらに次のステップとしてのスケルタルシステムの構築についてが語られているので,興味のある方は,ぜひ本書を手にとって頂きたい.


もちろんこれが設計の "how-to" になる訳ではないが,冒頭で述べたように「ガイダンス」として,なにかしらのヒントになるのではないかと思う.


0 コメント: