作業:
|
目的
|
|
役割: 設計者 | |
頻度: 反復ごとに 1 回。成果物: 設計ユース・ケースの実現のセットに対して行う。 | |
ステップ | |
入力とする成果物: | 結果となる成果物: |
ツール・メンター: | |
More Information: | |
ワークフローの詳細: |
システムの振る舞いは、コラボレーションや相互作用などの、さまざまな技法を使って表現できます。この作業では、相互作用、特にシーケンス図を使って、システムの振る舞いを記述します。シーケンス図は、システムまたはサブシステムの振る舞いを、主に同期メッセージで記述できる場合に役に立ちます。非同期メッセージ処理、特にイベント駆動型システムは、多くの場合状態マシンとコラボレーションを使った方が簡単に説明できます。これにより、オブジェクト間で起こり得る相互作用を簡単に定義できます。
成果物: 設計ユース・ケースの実現 は、設計モデルの振る舞いをユース・ケース・モデルに戻って追跡するための手段となります。また、設計モデルのコラボレーションをユース・ケースの概念に沿って整理できます。
>設計する各ユース・ケースについて、設計モデルで設計ユース・ケースの実現を作成します。設計ユース・ケースの実現の名前は、関連するユース・ケースと同じものにし、ユース・ケースの実現から関連するユース・ケースへの「実現」関係を確立します。
それぞれのユース・ケースの実現について、1 つ以上のシーケンス図を作成し、関係している設計オブジェクト間の相互作用を図解する必要があります。 こうしたシーケンス図の初期バージョンが、作業: ユース・ケース分析の間に作成されている場合もあります。 このようなユース・ケースの実現の「分析バージョン」は、分析クラス間の相互作用を示しています。 したがって、設計要素間の相互作用を示すように発展させる必要があります。
シーケンス図を更新するには次のステップに従います。
これらは、トップレベルの設計要素 (通常はサブシステムやサブシステムのインターフェース) のインスタンスの相互作用を示すシステム・レベルのシーケンス図です。サブシステムの内部設計を示すシーケンス図は、これとは別に、作業: サブシステム設計の一部として作成します。
アクティブ・オブジェクト (カプセル) の相互作用は、通常、仕様のコラボレーションと状態マシンを使って記述します。これらの要素は、大規模なユース・ケースの実現で、システムの他の要素がどのようにアクティブ・オブジェクト (カプセル) にメッセージを送信するのかを示すのに使用できます。典型的な例では、この作業のためにアクティブ・オブジェクト (カプセル) はサブシステム内にカプセル化され、ユース・ケースの実現は相互作用するサブシステム群で構成されます。この相互作用では、サブシステムの責務とインターフェースが定義されます。サブシステム内では、アクティブ・オブジェクト (カプセル) は並行実行スレッドを表します。サブシステムを使用することで、作業を開発チーム間で分割でき、インターフェースがチーム間の正式な契約の役目を果たします。
サブシステムからのメッセージを表現する場合の注: メッセージをインターフェースだけに制限すれば、モデル要素間の結合が減り、設計の柔軟性が向上します。可能な限り、このような制限の適用をお勧めします。サブシステムからインターフェースでないモデル要素へのメッセージがある場合は、これらのメッセージをインターフェース・モデル要素へのメッセージに変更できないかどうかを検討して、モデル内での結合をできるだけ少なくします。
オブジェクトによって実行されるユース・ケースの振る舞いを、シーケンス図内に文書化します。
オブジェクトへの振る舞いの分配が終了したら、フローの制御方法を検討します。ユース・ケースの実現では、オブジェクトがある種の方法で相互作用し、ある種の役割を持っていると仮定してオブジェクトを見つけました。振る舞いの分配を行いながら、この仮定をテストすることができます。フローのある部分では非集中型の構造を、別の部分では集中型の構造を使用したい場合もあります。この 2 種類の構造の定義と使い分けについては、『ガイドライン: シーケンス図』を参照してください。
この時点で、新しいオブジェクトが必要になることがあります。例えば、集中構造を使用し、フローを制御するために新しいオブジェクトが必要な場合などです。設計モデルに追加するオブジェクトは、オブジェクト・モデルに関する要求を満たす必要があることを忘れないでください。
作業: アーキテクチャー分析では、分析メカニズムを特定しました。 作業: 設計メカニズムの識別では、分析メカニズムを設計メカニズムへと発展させ、分析メカニズムから設計メカニズムへのマッピングをソフトウェア・アーキテクチャー説明書に記録し、設計メカニズムをプロジェクト固有のガイドラインに記録します。
この作業 (ユース・ケース設計) では、適用可能な設計メカニズムをすべてユース・ケースの実現に取り込みます。 設計者は、利用可能な設計メカニズムを調べて、現在のユース・ケースの実現に適用できるものを決定します。この調査は、「ソフトウェア・アーキテクチャー説明書」と「設計ガイドライン」の推薦やガイドラインに沿って行われます。
注: 適用可能な設計メカニズムが作業: ユース・ケース分析で既に特定されている場合もあります。そのような場合は、分析クラスに特定の分析メカニズムが「タグ」として付けられ、設計時に特定の機能が必要になることが示されています。 この場合、適用可能な設計メカニズムは、ユース・ケースの実現に含める分析クラスにタグ付けされている分析メカニズムに関連するものになります。
設計者は、必要な設計要素とそれらの相互作用をユース・ケースの実現に含めることによって、適用可能な設計メカニズムをユース・ケースの実現に取り込みます。その際には、「設計ガイドライン」に記述されている使用規則に従います。
フローの各バリエーションは別々のシーケンス図に記述します。 コミュニケーション図よりもシーケンス図の方が一般的に好まれるのは、システムの設計時に詳細情報をダイアグラムに記入するときにシーケンス図の方が読みやすいからです。
基本フローから記述を始めます。このフローは、イベント・フローの中でも最も一般的、かつ重要なものです。次に例外処理フローのようなバリエーションを記述します。関連するオブジェクトの全操作を取り入れ例証すれば、すべてのイベント・フローを記述する必要はありません。このため、1 つのオブジェクトにしか関係しないような、小さなフローは省略できます。
要求の取得と分析で既に記述済みのもの以外にフローのバリエーションがないか (例えば実装に依存するものなど)、ユース・ケースを検討します。新しいフローが見つかった場合は、各フローをシーケンス図に記述します。例外的なフローには、次のようなものがあります。
フローに代替パスがある場合には、バリエーションではなく、オプション・フローとして記述できます。次にオプション・フローの例を 2 つあげます。
オプションのフローや、複雑なサブフローを特に目立たせたい場合は、シーケンス図を別に分けて作成します。主なイベント・フローのシーケンス図に、スクリプト、余白へのテキストまたは注釈などを書き込んで、どこでオプションのフローやサブフローの振る舞いが発生するかを明確にし、個別に分けたシーケンス図を参照するようにします。
例えば、特定のイベントが発生したときに実行される振る舞いのように、オプションのフローまたは例外的なフローの振る舞いが発生する可能性がある場合は、主なイベント・フローのシーケンス図に注釈を付けて、そのイベントが発生するとオプションのフローまたは例外的なフローのシーケンス図に記述した振る舞いが実行されることを示します。または、重要なイベント駆動の振る舞いがある場合、ステートチャート図を使ってシステムの振る舞いを記述することもできます。詳細は、『ガイドライン: ステートチャート図』を参照してください。
ユース・ケースを実現する場合、イベント・フローは通常、実行しているオブジェクト、すなわち設計オブジェクト間の相互作用の観点から記述します。ダイアグラムを簡略化し、再利用可能な振る舞いを明確にするには、イベントのサブフローをサブシステムにカプセル化する必要があるかもしれません。これを行うと、シーケンス図中のまとまった部分を、サブシステムへの 1 つのメッセージで置き換えられます。サブシステム内では、独立のシーケンス図を使って、必要な振る舞いを提供するサブシステム内の内部相互作用を図示します (詳しくは、『作業: サブシステム設計』を参照してください)。
シーケンス図内のメッセージのサブシーケンスは、次のような場合にサブシステム内にカプセル化します。
必要であれば、ユース・ケースの実現はサブシステム階層にある複数のレベルとして記述できます。中央のダイアグラムの生存線はサブシステムを、円で囲んだ内部の相互作用はメッセージに対応するサブシステム構成要素間の内部相互作用を表します。
このアプローチの利点としては次のものがあります。
例:
次のシーケンス図を検討してください。これは「市内通話」ユース・ケースの実現の一部です。
のダイアグラムで灰色になっているクラスは、ネットワーク処理サブシステムに属しています。その他のクラスは加入者処理サブシステムに属しています。 つまり、このダイアグラムは複数のサブシステムによるシーケンス図です。このダイアグラムには、クラスが属するサブシステムに関係なく、イベント・フローに関連するオブジェクトがすべて含まれています。
また代替案として、ネットワーク処理サブシステム上の振る舞いの呼び出しと、そのサブシステム上での特定のインターフェースの働きを示すことができます。ネットワーク処理サブシステムでは、加入者処理サブシステムが使用する ICoordinator インターフェースが提供されると仮定します。
ICoordinator インターフェースはネットワーク処理サブシステム内のコーディネーター・クラスで実現されます。このため、シーケンス図では、ネットワーク処理サブシステム内のクラスのインスタンスではなく、ネットワーク処理サブシステム自体とその ICoordinator インターフェースを利用できます。
コーディネーター、番号情報、ネットワークの各クラス・インスタンスは、それらを含むサブシステムで置き換えられていることに注意してください。サブシステムへの呼び出しはすべて、ICoodinator インターフェース経由で行われるようになります。
同じインターフェースを実現するサブシステムを完全に置き換えられるようにするには、相互作用内 (およびダイアグラム全般) でインターフェースのみを表します。こうしないと、サブシステムを置き換える場合に、相互作用 (またはダイアグラム) も変更する必要がでてきます。
例:
シーケンス図の中には ICoordinator インターフェースのみを含め、インターフェースを提供するサブシステムは含めません。
メッセージをインターフェースの生存線に送信することは、そのインターフェースを実現するサブシステムが、ダイアグラム中のインターフェースと置き換え可能なことを意味します。ICoordinator インターフェースの生存線からは、送信されるメッセージはありません。これはインターフェースを実現するサブシステムが異なると、送信されるメッセージも異なる場合があるからです。ただし、インターフェースを実現するサブシステムからどのようなメッセージを送信するか (または、どのようなメッセージの送信を許可するか) を記述する場合は、このようなメッセージをインターフェースの生存線から送信できます。
場合によっては、サブシステムの開発を、他のサブシステムの開発と独立に並行して行うのが適切なことがあります。このためには、まずサブシステム間のインターフェースを明確にして、サブシステム間の依存性を見つける必要があります。
この作業は次のようにして行います。
また、シーケンス図をサブシステムの観点で整理するか、インターフェースのみの観点で整理するかを選択できます。プロジェクトによっては、モデリング作業を続行する前に、インターフェースを提供するクラスを実装しなければならない場合もあります。
オブジェクト指向パラダイムの全体目標は、実装の詳細カプセル化することです。したがって、永続性に関しては、永続オブジェクトを一時的オブジェクトのように見えるようにします。オブジェクトが永続的であることを意識したり、他のオブジェクトと区別して処理しなければならないようにすべきではありません。少なくともこれが目標です。
実際には、次のような場合に、アプリケーションで永続性の各種側面を制御する必要があります。
ここで検討するのは 2 つの場合です。オブジェクトが永続オブジェクト記憶に最初に書き込まれる場合と、オブジェクトの変更に伴ってアプリケーションにより永続オブジェクト記憶を更新する場合です。
どちらの場合も、詳細なメカニズムは永続的フレームワークによってサポートされている操作に依存します。一般的に、使用されるメカニズムは永続的フレームワークにメッセージを送信して、永続オブジェクトを作成します。オブジェクトが永続的になると、永続的フレームワークにより永続オブジェクトへの変更が自動検出され、必要に応じて (通常はトランザクションのコミットが行われるとき) 永続オブジェクト記憶に書き込まれます。
作成される永続オブジェクトの例を次に示します。
PersistenceMgr オブジェクトは永続的フレームワーク VBOS のインスタンスです。OrderCoordinator により永続的 Order が createPersistentObject メッセージの引数として PersistenceMgr に送られ、永続的 Order が作成されます。
イベント・シーケンスの特定の時点でオブジェクトが明示的に格納されることを確認する必要がない限り、一般的にはこれをモデル化する必要はありません。後の操作でオブジェクトをクエリーする必要がある場合は、オブジェクトがデータベースに存在しなければならないため、オブジェクトの存在を確認することが重要になります。
永続オブジェクト記憶からオブジェクトを読み込まない限り、アプリケーションによりそのオブジェクトにメッセージを送信することはできません。ご存じのように、オブジェクト指向システムでの操作は、オブジェクトにメッセージを送信することで行われます。ただし、メッセージの送信先となるオブジェクトがデータベース内にあり、メモリーに読み込まれていない場合には問題が起きます。すなわち、まだ存在していないものに対してメッセージを送ることはできないのです。
この状態を解決するには、データベースへのクエリー、適切なオブジェクトの取得、オブジェクトのインスタンス化を行えるオブジェクトにメッセージを送ります。このようにして初めて、予定していたメッセージを送信できます。永続オブジェクトをインスタンス化するオブジェクトは、ファクトリー ・オブジェクトと呼ばれることがあります。 ファクトリー・オブジェクトは、永続オブジェクトを含め、オブジェクトのインスタンス化を担当します。与えられたクエリーに対し、ファクトリー・オブジェクトはクエリーに適合する 1 つ以上のオブジェクトを戻すように設計できます。
一般に、オブジェクトは互いの関連により複雑にリンクされています。このため通常は、オブジェクト・グラフのルート・オブジェクトのみの取得が必要になります。残りのオブジェクトはルート・オブジェクトとの関連で、意識しなくてもデータベースから次々と「引き出されて」くることになります。(よい永続的メカニズムはこのあたりがうまくできており、必要なときだけオブジェクトを取り出すようになっています。そうでないと、不必要に多数のオブジェクトをインスタンス化する可能性があります。必要でないオブジェクトの取得は、単純な永続的メカニズムで生じる主な性能上の問題の 1 つです。)
次の例は、永続オブジェクト記憶からのオブジェクト取得をモデル化する方法を示しています。実際のシーケンス図では、DBMS は示さず、ファクトリー・オブジェクトにカプセル化します。
永続オブジェクトの問題は、これらのオブジェクトが永続することです。オブジェクトを作成したプロセスがなくなると消滅する一時的オブジェクトとは違い、永続オブジェクトは明示的に削除するまで存在します。したがって、不要になったオブジェクトは削除することが重要です。
問題は、いつオブジェクトが不要になったかの判断が困難なことです。あるアプリケーションでオブジェクトが不要になったからといって、現在から未来のアプリケーションすべてで不要になるとは言えません。また、オブジェクト自体でも認識されていない関連もあるため、オブジェクトを削除してよいかどうかを判断するのは必ずしも簡単ではありません。
設計段階では、これをステートチャート図を使ってセマンティックで表現できます。オブジェクトが終了状態に達すると、「解放」された、と言います。 永続的クラスの実装を担当する開発者は、このステートチャート図情報を使って、適切な永続的メカニズムの振る舞いを呼び出し、オブジェクトをリリースします。ユース・ケースを実現する設計者の責任は、オブジェクトを削除する場合に、適切な操作を呼び出してオブジェクトを終了状態に到達させることにあります。
オブジェクトが別のオブジェクトと複雑にリンクしている場合、オブジェクトを削除してよいかどうかを決定するのは難しくなります。ファクトリー・オブジェクトは、リンクしているオブジェクトだけでなく、そのオブジェクトの構造も認識しているため、多くの場合、クラスのファクトリー・オブジェクトによって、特定のインスタンスの削除に関する決定を行うと便利です。永続的フレームワークでも、この機能がサポートされることがあります。
トランザクションは、もうこれ以上分解できない (すべてを実行するのか、何も実行しないのかのどちらかしかできない) 原子的な操作呼び出しのセットを定義します。永続性のコンテキストでは、オブジェクトのセットに対してトランザクションが定義する変更のセットは、すべて実行されるか、またはまったく実行されません。トランザクションによって一貫性が提供され、オブジェクトのセットは、ある一貫した状態から別の一貫した状態に移行します。
ユース・ケースの実現でトランザクションを表現するには、いくつかの方法があります。
テキストによる注釈をつけてトランザクションの境界を表現
トランザクションの開始と停止を行うメッセージを明示するシーケンス図
トランザクション内で指定した全操作を実行できない場合 (通常はエラーによる)、トランザクションは中止され、トランザクション中に行った全変更が元に戻されます。予想されるエラー状態は、多くの場合、ユース・ケースの例外イベント・フローに示します。また、エラーがシステムの障害によって発生する場合もあります。エラー状態は、相互作用にも文書化するべきです。単純なエラーと例外は発生場所の相互作用に示されます。複雑なエラーと例外については、独自の相互作用を提供しなければならない場合もあります。
特定のオブジェクトの障害モードはステートチャート図に表現できます。このような障害モードの制御処理の条件付きフローは、エラーまたは例外が発生する場所の相互作用に示します。
並行性では、トランザクションにおける重要なシステム・リソースへのアクセス制御を記述します。システムを一貫した状態に保つために、トランザクションではシステムの中心となるリソースへ独占的にアクセスしなければならない場合があります。この場合の「独占的」には、オブジェクト・セットの読み込み、オブジェクト・セットの書き込み、またはその両方の能力が含まれることがあります。
オブジェクト・セットへのアクセスをなぜ制限する必要があるのかを簡単な例で見てみます。簡単な注文入力システムを考えてみましょう。顧客が注文を入れると、注文が処理され、製品が出荷されます。 この注文は一種のトランザクションとみなすことができます。
並行性制御のニーズを例示するために、ハイキング・ブーツを一足注文するとしましょう。注文がシステムに入ってくると、システムにより、希望のサイズのハイキング・ブーツが在庫にあるかどうかが確認されます。 在庫にある場合は、このブーツを予約して、出荷前に他の顧客が購入できないようにします。注文品を出荷したらブーツを在庫から削除します。
注文が入ってから品物が出荷されるまでの間、ブーツは在庫にはあるが、注文に「予約されている」という特殊な状態にあります。何らかの理由で注文をキャンセルすると (考えを変えた、またはクレジットカードの期限が切れていたなど)、ブーツは在庫に戻されます。注文品が出荷されると、ブーツが在庫にあったという記録は保持しないものと仮定します。
並行性の目標は、トランザクションと同様に、システムのある一貫した状態から別の状態への移行を保証することです。さらに、並行性は、トランザクションが作業を完了させるのに必要な全リソースを確保するように試みます。 並行性制御は、リソースのロック、セマフォー、共有メモリーのラッチ、プライベート・ワークスペースなど、各種の方法で実装できます。
オブジェクト指向システムでは、特定のメッセージがオブジェクトの状態の変化の原因となるかどうかを、メッセージ・パターンだけから特定するのは困難です。また、異なる実装により、ある種のリソースへのアクセスを制限する必要がなくなる場合もあります。例えば、実装によっては、すべてのトランザクション開始時に、システム状態の独自のビューを各トランザクションに提供することがあります。この場合、他のプロセスは、実行されているその他のトランザクションの「ビュー」に影響を与えることなくオブジェクトの状態を変更できます。
実装に制約を付けるのを避けるために、設計時には、トランザクションが独占的にアクセスする必要があるリソースを示すだけにします。 先ほどの例を使えば、注文したブーツへの独占的アクセスが必要だということを示します。また、簡単な代替案として、送信するメッセージの説明に注釈を付け、アプリケーションがオブジェクトへの独占的アクセスを必要とすることを示すこともできます。実装担当者はこの情報を使って、並行性要求をいかにうまく実装すべきかを決定します。次の例は、独占的アクセスを必要とするメッセージを注釈で示すシーケンス図です。 トランザクションが完了すると、すべてのロックが解除されると仮定しています。
シーケンス図で注釈付きのアクセス制御を示した例
トランザクションで、必要となる全オブジェクトへのアクセスを制限しない理由は、アクセス制限を持つオブジェクトの数をできるだけ少なくするためです。トランザクションに参加する全オブジェクトへのアクセスを制限すると、貴重なリソースを無駄にするだけでなく、性能上の問題点を作り出してしまいます。
ユース・ケースの実現のイベント・フローで、関連するオブジェクト間で送信されるメッセージを調べるだけではイベント・フローが完全には明確にならない場合は、シーケンス図に追加情報を記入します。このような例としては、外部からの参加者が比較的容易にダイアグラムを読めるようにするために、タイミングの記述、条件付き振る舞いへの注釈付け、操作の振る舞いの説明が必要となる場合があります。
イベント・フローは作業: ユース・ケース分析で最初に概要を示します。このステップでは、イベント・フローを改善して、シーケンス図を明確にします。
多くの場合、操作名だけではその操作がなぜ必要なのかを理解できません。ダイアグラムの余白にテキストによるメモやスクリプトを追加して、シーケンス図を明確にしなければならない場合があります。また、決定ステップ、ループ、分岐などの制御フローを表現するために、テキストによる注やスクリプトを追加することもあります。さらにテキストでタグを付けて、ユース・ケースの拡張点とシーケンス図内の特定の場所とを関係付けなければならない場合もあります。
この作業で示した以前の例では、シーケンス図にさまざまな方法で注釈を付けています。
ユース・ケースを実現する際には、明確にした設計クラスと設計サブシステムを統一して、設計モデル内の均質性と一貫性を確認します。
検討事項:
この段階で設計モデルをチェックして、作業が正しい方向に進んでいるか確認します。モデルを詳細にレビューする必要はありませんが、作業中に設計モデルのチェックポイントを確認するようにします。
特に、『作業: 設計レビュー』の『チェックポイント: ユース・ケースの実現』を参照してください。
シーケンス図でサブシステムを表現するのに、プロキシー・クラスを使用できます。このプロキシー・クラスはサブシステム内に含まれ、振る舞いの要素としてパッケージやサブシステムを直接使用することをサポートしないダイアグラムで、サブシステムを表現するのに使用します。あるメッセージに対して、特定のサブシステムが応答することを示す場合にプロキシー・クラスを使用します。この場合は、サブシステム・プロキシーから別のオブジェクトへ送信するメッセージを表現できます。
詳しくは、『UML 1.x と UML 2.0 の相違点 』を参照してください。
Rational Unified Process
|