作業:
|
目的 | システムが応答する必要のある内部と外部のイベントとシグナルを識別すること |
イベントは外部と内部で発生し、システム内に何らかのアクションを引き起こします。イベントとその特性によって、アクティブ・クラスなどの主要な設計要素を識別できます。
外部イベントの初期リストは、ユース・ケース・モデル、つまりアクターとユース・ケースの相互作用から導出できます。内部イベントは、ユース・ケースのフローのテキストから導出できます。または、設計が進む過程で識別できます。
イベントの重要な特徴には、次のものがあります。
イベントの特性は、それらを処理する設計要素を識別するために、必要に応じて把握する必要があります。イベントの特性を把握することは、リアクティブ (イベント駆動型の) システムで最も重要ですが、並行性か非同期メッセージ処理、またはその両方を使用するその他のシステムでも役に立ちます。
非同期通信のイベントは、それらが伝達するデータを表すシグナルとしてモデル化したり、汎化などのシグナル間の関係を表すためにモデル化したりできます。特にリアクティブ・システムなどの一部のシステムでは、外部デバイスから受け取ったシグナルを、割り込みや特定のポーリング・メッセージなどの特定のメカニズムに関連付けることが重要です。
目的 | 分析クラスを適切な設計モデル要素に洗練すること |
クラスの識別: 分析クラスが単純で、既に 1 つの論理的抽象概念を表現している場合、直接設計クラスに 1 対 1 でマッピングできます。通常、エンティティー・クラスは比較的そのまま設計に持ち込めます。エンティティー・クラスは通常、永続的でもあるため、設計クラスが永続的であるべきかを決定し、決定した内容をクラスの定義に注記します。
クラスを識別するときは、組織と構成管理の都合上、成果物: 設計パッケージにグループ化します。 パッケージングの決定方法について詳しくは、『ガイドライン: 設計パッケージ』を参照してください。
アクティブ・クラスの識別: システムの並行性要求は、識別した分析オブジェクトのコンテキストで検討します。つまり、外部で生成されたイベントに対してシステムが応答する必要があるかどうか、そして、その場合は、イベントの発生時にどの分析クラスが「アクティブ」になっているかというように検討します。ユース・ケース・モデルにおける外部イベントは、アクターからの刺激として表現され、ユース・ケースと相互作用します。イベント発生時にどのオブジェクトが相互作用するかを知るには、対応するユース・ケースの実現を見ます。まず、オブジェクトを、コラボレートするオブジェクトの独立したセットにグループ化します。このグループ化は、コンポジット・アクティブ・クラスを形成するグループへの最初の切り取りを表現します。
イベントに把握する必要のある重要な属性がある場合は、それらを <<signal>> としてステレオタイプ化されるクラスとしてモデル化することを検討します。
アクティブ・クラスのインスタンスは、独立した「論理的な」実行スレッドを表現します。これらの「論理的な」実行スレッドは、まだ、オペレーティング・システムの実行スレッドと混同したり、文字どおりにマッピングすべきではありません (ただし、将来のある時点で、オペレーティング・システムの実行スレッドにマッピングします)。代わりに、ソリューション空間における独立した概念的実行スレッドを表現します。設計のこの段階でこれらを識別する目的は、システムの自然な「並行性の継ぎ目」に沿って、解決法を独立した部分に分割できるようにすることにあります。このように作業を分割すると、並行性の問題に対処することが概念的にずっと簡単になります。独立した実行スレッドは、下位のパッシブ・クラスを共有するという点を除いては別個に扱えるからです。
一般的に、並行性があり、問題のドメインで並行性が衝突を起こす場合にはアクティブ・クラスの使用を検討すべきです。外部の並行オブジェクトまたはコンピューター内の並行作業を表現するには、アクティブ・クラスを使用する必要があります。これによって、並行作業を監視し、制御できるようになります。
もう 1 つのよくある選択は、アクティブ・クラスをコンピューターに接続された外部物理デバイスの内部表現として使用することです。物理的なエンティティーは元来、並行的であるためです。この「デバイス ・ドライバー」クラスは、対応する物理デバイスを監視し制御するだけなく、残りのシステムをデバイスの仕様から隔離します。これは、デバイスの技術が進歩した場合にも、周囲のシステムが影響を受けないことを意味しています。
この他に、アクティブ・クラスを一般的に使用するのは、論理的な並行作業を表現する場合です。論理的な作業では、金融関係のトランザクションや電話呼び出しのように、概念的に並行な「オブジェクト」を表現します。これらは (物理的世界では発生するものの) 物理的エンティティーとして直接現れているものではないという事実に反して、物理的に扱う理由が多数あります。例えば、並行的な衝突を防ぐために特定の金融トランザクションを一時的に保留したり、システム内の障害のためにトランザクションを中止する必要が生じる場合があります。このような概念的オブジェクトは 1 つの単位として操作する必要があるため、適切な機能を提供する独自のインターフェースを持つオブジェクトとして表現すると便利です。
このタイプの概念的オブジェクトを表す具体的な例としてはアクティブ・オブジェクト・コントローラーがあります。このコントローラーの目的は 1 つ以上のアクティブ・オブジェクトを連続的に管理することです。それには、通常、各オブジェクトを望ましい運用状態にしたり、部分的な障害のような各種の混乱があってもその状態を維持したり、その他のオブジェクトの操作と同期したりする作業が必要になります。このアクティブ・オブジェクト・コントローラーは多くの場合、作業: ユース・ケース分析中に識別したコントロール・オブジェクトから発展します。
アクティブ クラスには並行性の衝突を簡単かつ素早く解決する能力があるため、共有リソースの監視役としても役立ちます。この場合には、複数の並行作業で必要な 1 つ以上のリソースが 1 つのアクティブ・クラス内にカプセル化されます。内蔵された排他的なセマンティクスによって、これらの監視機能は並行性の衝突からリソースを自動的に保護します。
サブシステムの識別: 分析クラスが複雑で、単一のクラスの責務を超える振る舞いを具体化していると思われる場合は、分析クラスを設計サブシステムにマッピングします。設計サブシステムは、このようなコラボレーションをカプセル化するために使用されます。サブシステムのクライアントは、サブシステムが提供するサービスを使う場合であっても、サブシステムの内部設計を知る必要はまったくありません。
サブシステムは UML コンポーネントとしてモデリングされます。UML コンポーネントには、パブリック要素としてのインターフェースのみがあります。このインターフェースはカプセル化のレイヤーを提供するため、サブシステムの内部設計は他のモデル要素からは隠れて見えません。概念サブシステムは、これをパッケージから区別するために使用します。パッケージは、セマンティクスがないモデル要素のコンテナーです。
コラボレートする分析クラスのセットからサブシステムを形成するかどうかの決定は、独立した設計チームがコラボレーションを独立して開発できるかどうか、または実際に開発するのかという点に大きく依存します。コラボレーションをコラボレートするクラスと共に 1 つのパッケージ内に完全に収容できる場合は、単純なパッケージによって提供されるよりもずっと強力なカプセル化の形態がサブシステムによって提供されます。サブシステム内部のコンテンツとコラボレーションは 1 つ以上のインターフェースの背後に完全に隔離されるため、サブシステムのクライアントはそのインターフェースのみに依存することになります。したがって、サブシステムの設計者は外部依存性から完全に切り離されます。設計者 (または設計チーム) は、インターフェースを実現する方法を特定する必要はありますが、外部依存性に影響を与えることなく内部のサブシステム設計を自由に変更することができます。独立性の高いチームを持つ大規模なシステムでは、この分離度の問題が、正式なインターフェースによって提供されるアーキテクチャーの実施と併せて、単純なパッケージとサブシステムのどちらを選択するかという大きな争点になります。設計要素としてサブシステムを使用するという選択に影響を与える要素について詳しくは、『ガイドライン: 設計サブシステム』を参照してください。
目的 | システム内の継ぎ目を形式化する設計要素を識別すること |
インターフェースは、何らかの分類子によって実現される操作のセットを定義します。 設計モデルでは、インターフェースは主にサブシステムのインターフェースを定義するために使用されます。これは、インターフェースをクラスに使用できないことを意味するわけではありません。単一のクラスの場合、通常、そのクラスに public 操作を定義するだけで十分で、実際上これで「インターフェース」を定義していることになります。インターフェースは、サブシステムにとって重要です。振る舞いの宣言 (インターフェース) と振る舞いの実現 (インターフェースを実現するサブシステム内の特定のクラス) の分離を可能にするからです。この分離により、システムの異なる部分に従事する開発チームの独立性を向上させる方法が得られる一方で、この異なる部分間の「契約」の正確な定義を維持できます。
サブシステムごとのインターフェース候補セットの識別: 以前のステップで識別した、グループ化されたコラボレーションを使用して、コラボレーション開始時に「アクティブにする」責務を識別します。その後、「クライアント」によって提供されるべき情報は何か、およびコラボレーションの完了時に返される情報は何かを決定することによって洗練を行います。これらの情報のセットは、プロトタイプの入出力パラメーターになり、サブシステムによって実現される操作の戻り値になります。
成果物: プロジェクト固有のガイドラインで定義した命名規約を使用して、この操作の名前を定義します。
サブシステムによって実現される全操作の定義が完了するまでこれを繰り返します。
次に、関連する責務に従って操作をグループ化します。 グループ内の操作が少ない場合はまとまりの強い共通の責務のセットが存在する可能性が高くなるので、大規模なグループよりも小規模なグループのほうが適しています。再利用にも目を向けます。関連する再利用可能機能の識別が容易になるような類似性を探します。ただし、この時点で責務の理想的なグループ化を探そうとして多大な時間を費やさないようにします。これは最初のグループ化であり、推敲フェーズを通して繰り返し洗練を進めることになります。
インターフェース間の類似性の探索: インターフェース候補のセットから、類似した名前、類似した責務、類似した操作を探します。複数のインターフェースに同じ操作がある場合は、これらのインターフェースを再度分解し、共通操作を抽出して、新しいインターフェースにします。既存のインターフェースも同様に見直し、可能であれば再利用します。目標は、インターフェースの一貫性を維持する一方で、インターフェース間の冗長な操作を削除することです。これによって、インターフェースは理解しやすくなり、発展していけるようになります。
インターフェースの依存性の定義: 各インターフェース操作のパラメーターと戻り値にはそれぞれ特定の型があります。これらは、特定のインターフェースを実現したり、単純なデータ型のインスタンスであったりする必要があります。パラメーターが特定のインターフェースを実現するオブジェクトである場合は、そのインターフェースと、インターフェースが依存するインターフェースとの間の依存関係を定義します。インターフェースの依存性によって設計モデルの要素間の主要な依存性が定義されるので、インターフェース間に依存性を定義することで、ソフトウェア・アーキテクトに有益な結合情報が提供されます。
サブシステムへのインターフェースのマッピング: インターフェースを識別したら、サブシステムと、このサブシステムによって実現されるインターフェースとの間に実現関連を作成します。サブシステムからインターフェースへの実現は、インターフェースの操作を実現する要素がサブシステム内に 1 つ以上存在することを示します。後でサブシステムを設計するとき、サブシステム設計者が、サブシステム内のどの特定要素がインターフェースの操作を実現するかを指定し、このサブシステムからインターフェースへの実現を洗練します。これらの洗練された実現は、サブシステム設計者にしか見えません。サブシステムのクライアントの見地からは、サブシステムからインターフェースへの実現だけが見えます。
インターフェースで指定する振る舞いの定義: インターフェースによって、インターフェースを実現する要素について暗黙の状態マシンが定義されることがよくあります。インターフェース上の操作を特定の順序で呼び出す必要がある場合 (データベースの使用前にデータベース接続をオープンする必要がある場合など) は、インターフェースを実現する設計要素がサポートする必要がある、一般に可視的な (または推測できる) 状態を示す状態マシンを定義します。 この状態マシンによって、インターフェースのユーザーはインターフェースをより深く理解できるようになり、インターフェースを実現する要素の設計者は、担当する要素に正しい振る舞いをさせることができるようになります。
インターフェースのパッケージ化: インターフェースはソフトウェア・アーキテクトが所有します。インターフェースへの変更は常に、アーキテクチャー上重要です。これを管理するには、ソフトウェア・アーキテクトが所有する 1 つ以上のパッケージにインターフェースをグループ化します。各インターフェースが単一のサブシステムによって実現される場合、インターフェースはサブシステムと同じパッケージ内に配置できます。インターフェースが複数のサブシステムで実現される場合は、これらのインターフェースをソフトウェア・アーキテクトが所有する独立したパッケージ内に配置します。これによって、インターフェースをサブシステムから独立して管理、制御できるようになります。
UML 1.5 に従うと、サブシステムは、インターフェースのみをパブリック要素として持つ特殊なパッケージにするのが効果的です。このインターフェースはカプセル化のレイヤーを提供するため、サブシステムの内部設計は他のモデル要素からは隠れて見えません。概念サブシステムは、これを「通常の」パッケージから区別するために使用します。「通常の」パッケージは、セマンティクスがないモデル要素のコンテナーであり、サブシステムは、クラスに似た (振る舞いに関する) プロパティーがあるパッケージの特定の使用方法を表現します。
詳しくは、『UML 1.x と UML 2.0 の相違点 』を参照してください。
Rational Unified Process
|