ObectSquare

[UMLとオブジェクト指向分析・設計が開発リスクを軽減する]


アーキテクチャ設計

 設計作業に入る前に,まずシステム全体のアーキテクチャを決めます.アーキテクチャとはシステムの基本的な構造や制御の流れを指します.言い換えれば,システム全体のマクロな設計方針ともいえます.組み込みシステムの場合は,ハードウェアの変更などに柔軟に対応できるようなクラス構成やシステムの制御方法を決めるスレッド設計などが中心となります.

(1)システムの階層化
 オブジェクト指向ではクラスを使用することで変更に対する柔軟な構造を実現していますが,クラスの数が多くなるとその管理が大変になり,それだけでシステムの大きな変更に対応することは難しくなります.そのため,クラスより大きなレベルで,あらかじめ変更に耐え得るようなシステムの構造を設計しておくことが必要です.ここではそういったシステムの構造として最も一般的な階層化について考えてみましょう.
 まず,システムをその役割に応じて階層的に分割します.上位の階層ほどシステムに固有の制御や表現などを受け持ち,通常の変更はこの階層内で吸収します.下位の階層はシステムに影響されないドメイン固有の機能を提供します.分析で見つけたサブシステムやクラスは主にこの階層に含まれます.
 複数の階層で共通に使用するサービスなどについては,それらを提供するグループを作ります.これらのグループやそこに含まれるクラスはシステムを構築する際に必要となるもので分析モデルには含まれていません.アーキテクチャ設計を行うことにより新たに見つけ出されることになります.
 そして最後にこれらの階層やグループを適切な依存関係で結びます.
 このようにして作成されたシステムは,変更範囲を特定の階層に局所化することができるため,変更への対応が容易になります.また,汎用的な階層のクラスは再利用性を増します.
 組み込みシステムの場合には,さらにハードウェアの変更から受ける影響を最小限にするためにハードウェアラッパーと呼ばれる階層が追加されます.
 主な各階層やグループとしては次のようなものが考えられます.

●ルート
 システムの起動,終了に関わるグループで,スタートアップルーチンから呼び出されるクラス,初期化を行うクラス,システム全体の生成を行うクラスなどから構成されます.

●システム制御
 システム全体にわたる振る舞いや,各サブシステム間の制御を行います.

●アプリケーション
 システム固有のドメインに特化しない処理を行う階層です.ユースケースによる分析で導出したコントローラの一部や,どのサブシステムにも属さない処理を表わすクラスなどはここに含まれます.

●ドメイン
 システムで扱う問題領域の中心を表わします.分析で導出したシステムの対象となるクラス,システムのコンセプトを表わすクラスなどが含まれます.

●ハードウェアラッパー
 システムで制御するハードウェアを表わします.分析で導出したハードウェアラッパーから構成されます.

●共通ファシリティ
 システム全体で使用するユーティリティ的なサービスを提供します.タイマーやログ出力,エラー処理に関するクラスなどから構成されます.

●分散
 複数ノードに分散しているシステム等では,分散処理に必要となるクラスをまとめます.CORBAやDCOMなどを用いた場合にIDLから作成されるクラスなどがここに含まれます.

●オペレーティングシステム
 OSの提供するサービス群(API)を抽象的なインターフェイスで提供します.プロセスやスレッド,メッセージキュー,セマフォなどのクラスから構成されます.ただし,このグループをどの程度まで充実させるかは汎用性と効率とのトレードオフになります.
 それでは実際にエレベータシステムを使って階層化の作業を行ってみましょう.各階層はサブシステムと同様にパッケージとして表わします.
 まず,システム全体のルートパッケージを追加します.エレベータ選択サブシステムはアプリケーション層に該当します.また,エレベータおよびフロアの各サブシステムはその内部をアプリケーション,ドメイン,ハードウェアラッパーに階層化できます.たとえば,エレベータコントローラはアプリケーション,エレベータの運行スケジュールはドメイン,各ハードウェアはハードウェアラッパーにそれぞれ該当します.今回のシステムでは各階層に数個のクラス程度しか存在していないので特にパッケージとしては分割していませんが,今後各レイヤーのクラスが増えていく可能性が高ければ各レイヤーごとにパッケージとして分割しておくほうがよいかもしれません.また,エレベータパッケージの各オブジェクトを生成するエレベータファクトリークラスを追加し,ハードウェアラッパークラスにはステレオタイプを付与します.図7と図8にこれらの検討を行った最上位パッケージ,エレベータパッケージをそれぞれ示します.
 なお,特定の用途に合わせたフレームワークを作る場合には,階層をさらに汎用部分とカスタマイズ部分に分けて考える必要があります.
 

図7:最上位パッケージ


図8:エレベータパッケージ


(2)スレッドの設計
 ユースケースの項で述べたように,ビジネス系のソフトウェアでは通常ユーザーからの入力が一連の処理の契機になるのに対し,組み込みシステムでは,外部環境からのいろいろなイベントを契機に処理が実行されます.ですからシステムの制御構造には,同時に発生するこれらのイベントに迅速に対応できる能力が必要とされます.これらに一番大きな影響を与えるのはスレッドの設計です.以下では組み込みシステムのスレッド設計方法のいくつかについて具体的に考えてみます.

●シングルスレッドで処理する
 外部からの割り込みをいったんすべてイベントに変換し,メッセージキューに保持します.main処理の中では永久ループでメッセージキューからイベントを取りだし,該当するオブジェクトのメソッドを呼び出します.この方法のメリットとしては,簡単なこと,制御のためのOSが不要なためCPUパワーをすべて使用できること,などがあげられます.デメリットは,単一スレッドのため並行処理が行えないことです.いずれにしても,この方法はあまり大きくない,リソースの制限されたシステムで採用されることが多いようです.

●ひとつのイベントをひとつのスレッドで処理する
 外部からのイベントを並列に処理するため,イベントを処理する一連のパスごとにスレッドをひとつ割り当てます.つまり,ひとつのイベント処理の実行パスのすべてをひとつのスレッドに割り付けます.これを実現するためには,あらかじめイベントに割り当てるスレッドをまとめて生成しプールしておき,イベント発生に応じその処理を行うパスにスレッドを割り当てる等の処理が必要になります.
 この方法のメリットとしては,プリエンプティブな並行処理が可能なこと,オブジェクト呼び出しが関数コールとなるため呼び出しにかかるコストが小さいことなどがあげられます.一方,並行に行われるイベント処理間で共有されるオブジェクトが多くなる場合には,リエントラントな呼び出しが多発することになります.クラスがリエントラントでない場合には,これを防ぐためにクラスの各メソッドをクリティカルセクションやセマフォなどを使用して排他制御する必要があります.また,それによる効率の低下も問題になってきます.
 この方法のイメージを図9に示します.ひし形がスレッドを,角の丸い四角がオブジェクトを表わします.黒丸はパスの開始点をバーはパスの終了を示します.

図9:ひとつのイベントをひとつのスレッドで処理する


●ひとつのイベントを複数のスレッドで処理する
 この方式では特定の責務単位にスレッドを割り当てます.ですからイベントを処理する一連のパスは複数のスレッドの協調処理で実現されることになります.この方法では,原則としてスレッド内では同期呼び出しを使用し,スレッド間ではメッセージキューなどを介した非同期呼び出しを使用します.他のスレッドへの要求はメッセージキューなどによりいったん直列化されるため,先の方式とは異なりリエントラントな呼び出しへの配慮は不要になります(ただし共有リソースを保護するための排他制御は必要です).
 この方法の場合,さらに責務の分け方によっていくつかのスレッドパターンが存在します.たとえば「マスタースレーブ」パターンではひとつの作業をいくつかのスレーブに分割して並行に作業させます.「パイプライン」パターンはひとつの作業に対し,各スレッドが決められた順番どおりに流れ作業的に処理を行う方法です.
 一般的なマルチスレッド処理の場合は通常この方法がとられます(スレッドのパターンは最適なものが選択されます)が,スレッド間でのオブジェクト呼び出しを非同期通信に変換しなければならないこと,および非同期通信自体のコスト等を考慮しておく必要があります.この方法のイメージを図10に示します.
 エレベータシステムでは,スレッド設計についてはこの方法を採用することにします.なお,これ以降の具体的な検討はこの後の設計フェーズで行います.

図10:ひとつのイベントを複数のスレッドで処理する


© 1999 OGIS-RI Co., Ltd.
Prev Index Next
Prev. Index Next