目的
  • ユース・ケースの実現に必要な振る舞いをクラスが提供することを保証する
  • あいまいにクラスを実装しないために、十分な情報を提供することを保証する
  • クラスに関係する機能外要求を処理する
  • クラスで使用する設計メカニズムを組み込む
役割:  設計者 
頻度: 反復ごとに 1 回 
ステップ
入力とする成果物:    結果となる成果物:   
ツール・メンター:   
More Information: 

ワークフローの詳細:   

クラスは、設計作業をこなす作業担当として、システムの実際の作業を遂行します。その他の設計要素であるサブシステム、パッケージ、およびコラボレーションは、クラスのグループ化の方法、あるいはクラスの相互運用方法を記述します。

アクティブ・クラスは、パッシブ・クラスの振る舞いを調整および駆動する設計クラスです。アクティブ・クラスのインスタンスはアクティブ・オブジェクトであり、このオブジェクトはそれ自体の制御スレッドを備えています。

設計パターンとメカニズムの使用ページの先頭へ

設計パターンおよびメカニズムを、設計するクラスまたは機能に適合するように、かつプロジェクト設計ガイドラインに従って使用します。

パターンおよびメカニズムの組み込みはこの作業の後続の手順 (新規のクラス、操作、属性、および関係の追加) の多くを効果的に実行しますが、パターンまたはメカニズムにより定義されるルールに従います。

パターンとメカニズムは通常、設計の進展と共に組み込まれるものであり、この作業の最初の手順としてだけでないことに注意してください。パターンとメカニズムは単一のクラスだけでなく、クラスのセットにも頻繁に適用されます。

初期設計クラスの作成ページの先頭へ

この作業への入力として与えられている分析クラスに対して 1 つまたは複数の初期設計クラスを作成し、追跡依存関係を割り当てます。このステップで作成した設計クラスは、分析クラスの設計方法を説明するさまざまな設計プロパティーを割り当てる後続のステップで、改良、調整、分割あるいは統合されます。この設計プロパティーには、操作、メソッド、および状態マシンなどがあります。

設計対象の分析クラスのタイプ (境界型、エンティティー型、コントロール型) に応じて、初期設計クラスの作成に使える特定の戦略が決まります。

バウンダリー・クラスの設計

バウンダリー・クラスはユーザーに対するインターフェースまたは他のシステムに対するインターフェースのいずれかを表します。

他のシステムへのインターフェースを表すバウンダリー・クラスは、内部の振る舞いが複雑なことが多いため、サブシステムとしてモデル化することが一般的です。インターフェースの振る舞いが単純な (外部システムに対する既存の API へのパススルーとしてのみ働く) 場合は、1 つまたは複数の設計クラスを使ってインターフェースを表すことができます。この方法を選択した場合は、プロトコル、インターフェース、または API ごとに単一の設計クラスを使い、クラスの特殊な要求の中で、使用する標準などについての特殊な要求に着目します。

ユーザーに対するインターフェースを表すバウンダリー・クラスは、通常、ユーザー・インターフェース中の各ウィンドウについて 1 つのバウンダリー・クラス、または各フォームについて 1 つのバウンダリー・クラスというルールに従います。 この結果として、バウンダリー・クラスの責任はかなりハイレベルなものになり、このステップで改良し、詳細を詰める必要があります。ユーザー・インターフェースの追加モデルまたはプロトタイプは、この手順で考慮すべきもう 1 つの入力ソースになることが考えられます。

バウンダリー・クラスの設計は、プロジェクトで使用できるユーザー・インターフェース (UI) 開発ツールによって異なります。現在の技術を使用し、開発ツール内で UI を直接ビジュアルに構築するのが一般的です。これにより、コントロールおよびエンティティー・クラスの設計に関連付ける必要のある UI クラスが自動的に作成されます。UI 開発環境が UI を実装するために必要なサポートするクラスを自動的に作成する場合、それらを設計の中で考慮する必要はありません。 開発環境で自動的に作成されないものを設計するだけです。

エンティティー・クラスの設計

分析時に、エンティティー・クラスは情報の操作される単位を表します。 エンティティー・クラスは、パッシブかつ永続的であることが多く、永続性の分析メカニズムとして識別され、関連付けられることがあります。 データベースをベースとした永続性メカニズム設計の詳細は、『作業: データベース設計』で説明します。性能を考慮した場合、永続的なクラスの再編成が必要になり、役割: データベース設計者役割: 設計者との間で共同で議論される設計モデルへの変更を伴う場合があります。

永続的クラスの設計問題に関する幅広い議論が、後述の『永続的クラスの識別』に示されています。

コントロール・クラスの設計

コントロール・オブジェクトには、ユース・ケースの流れを管理する責任があり、ユース・ケースのアクションのほとんどを調整します。コントロール・オブジェクトは、ユーザー・インターフェースの問題 (境界オブジェクト) またはデータ工学の問題 (エンティティー・オブジェクト) には特に関係していないロジックをカプセル化します。このロジックは、アプリケーション・ロジックまたはビジネス・ロジックと呼ばれることがあります。

コントロール・クラスを設計する際に以下の課題を考慮してください。

  • 複雑性 - バウンダリー・クラスまたはエンティティー・クラスを使用し、振る舞いのコントロールまたは調整を単純化して処理できます。ただし、アプリケーションが複雑になるにつれて、この方法に対する大きな反動が表面化してきます。
  • ユース・ケースを調整する振る舞いが UI の中に埋め込まれるようになり、システム変更がますます難しくなります
  • 異なるユース・ケースの実現中では、同じ UI を簡単には使えません
  • UI に余分な機能が付いて重荷となり、性能を劣化させます
  • このエンティティー・オブジェクトにはユース・ケース特有の振る舞いが付いて回るようになり、汎用性が減少します

このような問題を避けるために、コントロール・クラスを導入して、イベント・フローの調整に関する振る舞いを提供しています。

  • 変更の可能性 - イベント・フローが変わる確率が低かったり、かかるコストがごくわずかであれば、コントロール・クラスを追加する費用と複雑さは正当化されません。
  • 分散と性能 - アプリケーションの各部を別ノード上あるいは別のプロセス空間で動作させる必要があると、設計モデルの要素を特化する必要性が生まれます。この特化はほとんどの場合、コントロール・オブジェクトを追加し、振る舞いをバウンダリー・クラスとエンティティー・クラスからコントロール・クラスへ分散させることで実現できます。こうすることで、バウンダリー・クラスは純粋な UI サービスの提供へ、またエンティティー・クラスは純粋なデータ・サービスの提供へと移行し、コントロール・クラスが残りの機能を提供するようになります。
  • トランザクション管理 - トランザクション管理は、古典的な調整作業です。トランザクション管理を処理するためのフレームワークがない場合、1 つ以上のトランザクション・マネージャー・クラスの相互作用によりトランザクションの整合性を確保しなければなりません。

後の 2 つの場合で、コントロール・クラスが独立した制御スレッドであるときは、アクティブ・クラスを使って制御スレッドをモデル化することがさらに適している場合があります。

永続的クラスの識別ページの先頭へ

永久媒体上に状態を格納する必要のあるクラスを、「永続的」であると言います。状態の格納は、クラス情報の永久記録やシステム障害時のためのバックアップ、あるいは情報交換のために必要となります。永続的クラスは、永続的インスタンスと一時的インスタンスの両方を持っていることがあります。あるクラスを永続的と言うのは、単にクラスのいくつかのインスタンスが永続的である必要があるという意味です。

また、分析中に発見した永続性メカニズムに対応する設計メカニズムも組み込みます。例えば、クラスによって必要となるものによって、永続性の分析メカニズムは以下の設計メカニズムのいずれかにより実現される場合があります。

  • メモリー内記憶
  • フラッシュ・カード
  • バイナリー・ファイル
  • データベース管理システム (DBMS)

永続的オブジェクトはエンティティー・クラスからのみ派生するわけではありません。永続的オブジェクトは一般に機能外要求を処理するためにも必要となる場合があります。 例としては、プロセス制御に関する情報を保持したり、トランザクション間の状態情報を保持したりするために必要な永続的オブジェクトがあります。

永続的クラスを識別することは、役割: データベース設計者に、このクラスが物理的格納特性に特別な注意が必要であることを知らせるのに役立ちます。これはまた、役割: ソフトウェア・アーキテクトに対しクラスが永続的である必要があること、および役割: 設計者に対しクラスのインスタンスを永続的にする必要があることも知らせます。

調和のとれた永続的な方針が必要なため、役割: データベース設計者は、永続的なフレームワークを使って永続的クラスをデータベースにマッピングする責務を負います。プロジェクトで永続的フレームワークを開発している場合、フレームワーク開発者は設計クラスの永続的な要求も把握しておく責任があります。このような人々に必要な情報を提供するには、この時点では、クラスが永続的であること、またはより正確にいえばクラスのインスタンスが永続的であることを示すだけで十分です。

クラスの可視性の定義 ページの先頭へ

各クラスに対して、そのクラスが存在しているパッケージでのクラスの可視性を決定します。public クラスは、それが含まれているパッケージの外側から参照可能です。private クラス (または可視性がimplementation のもの) は、同一パッケージ内のクラスからのみ参照可能です。

操作の定義 ページの先頭へ

操作の識別

設計クラスで操作を識別するには

  • 対応する各分析クラスの責任を調べ、その責任ごとに操作を 1 つ作成します。その操作の初期記述として、この責任に関する記述を使用します。
  • 参加する クラスでのユース・ケースの実現を調べ、操作がユース・ケースの実現でどのように使用されるかを確認します。その時点における 1 つのユース・ケースの実現に対する操作を拡張し、操作自体、操作の記述、戻り型、およびパラメーターを詳細化します。各ユース・ケースの実現の、クラスについての要求は、ユース・ケースの実現のイベント・フローにテキストで記述されています。
  • 特殊要求ユース・ケースを調べて、そこで述べられる可能性のある操作上の暗黙の要求を見逃さないようにします。

操作は、シーケンス図に提示されるメッセージをサポートする必要があります。これは、スクリプト、つまり操作にまだ割り当てられていないメッセージ (一時的なメッセージ仕様) で、クラスが遂行すると思われる振る舞いを記述するからです。 図 1 はシーケンス図の例を示しています。

付随するテキスト内で説明される図

図 1: 操作識別の基礎を形成するメッセージ

ユース・ケースの実現では、すべての操作を明確にするための十分な情報を提供できません。明確になっていない操作を探すには、次のことを検討してください。

  • クラスの新インスタンスを初期化する方法はありますか。これには、関連している他のクラスのインスタンスに接続する場合も含めます。
  • クラスの 2 つのインスタンスが等しいかどうかをテストする必要性はありますか。
  • クラス・インスタンスのコピーを作る必要性はありますか。
  • 使用するメカニズムによってクラス上で必要となる操作はありますか。例えば、ガーベッジ・コレクション のメカニズムが未使用のリソースを解放するために、あるオブジェクトが他のすべてのオブジェクトへの参照をすべて中止できなければなりません。

public 属性の値を単に取得および設定する操作を定義しないでください (『属性の定義』と『関連の定義』を参照)。通常、これらはコード生成機能により生成され、明示的に定義する必要はありません。

操作の命名と説明

操作、戻り型、パラメーターとそれらの型を命名する場合は、実装言語用の命名規則を利用します。

各々の操作に対して、次を定義してください。

  • 操作名 - 名前は短くし、操作によって得られる結果を説明するものにします。
    • 操作名は実装言語のシンタックスに従います。find_location は C++ あるいは Visual Basic では受け入れられますが、Smalltalk では受け入れられません (下線は使用できないため)。すべてに共通のよい名前として findLocation があげられます。
    • 操作の実行方法を想像させるような名前は避けます。例えば、Employee.wages() の方が Employee.calculateWages() よりも適しています。後者は計算が実行されることを想像させるからです。この操作はデータベース内の値を単に戻すだけです。
    • 操作名は、その目的を明白に示すことが必要です。具体的でない名前は避けます。例えば、getData のような名前では、戻される結果が説明されません。何を期待しているかを正確に示す名前を使います。例えば、getAddress のようなものです。ただしもっと適切なのは、操作名を単純に返される、または設定されるプロパティーの名前にすることです。パラメーターがある場合はプロパティーを設定します。パラメーターがない場合はプロパティーを取得します。 例えば、address という操作は顧客のアドレスを戻しますが、address(aString)顧客のアドレスを設定したり変更したりします。操作の持つ取得設定 の性質は、操作のシグニチャーを見るとわかります。
    • 概念的に同じ操作は、異なるクラスで定義されていても、まったく異なる方法で実装されていても、あるいはそのパラメーター数が異なっていても、同じ名前にすべきです。例えば、オブジェクトを生成する操作はすべてのクラスで同じ名前にすべきです。
    • 複数のクラスの操作が同じシグニチャーを持つ場合は、操作は受け手のオブジェクトに適切な同じ種類の結果を返す必要があります。これは多態性という概念の例で、異なるオブジェクトが同じメッセージに同じように反応すべきことを示しています。例えば、操作の name は、その名前の格納方法や由来の如何にかかわらず、オブジェクト名を戻す必要があります。この原則に従うと、モデルを理解しやすくなります。
  • 戻り型 - 戻り型は操作の結果戻されるオブジェクトのクラスであるべきです。
  • 短い説明 - できるだけ意味を持たせるようにするものの、操作名で操作の動作を理解しようとしてもほんのわずかしか役に立ちません。操作に対してユーザーの視点から書いた数行の短い説明を付けます。
  • パラメーター - 各パラメーターに対して、短い説明的な名前を付け、クラスを決定し、簡単な説明を付けます。パラメーターを指定する際は、パラメーターの数が少ないほど、再利用性が高くなることを覚えておいてください。パラメーターの数が少ないと、操作は理解しやすくなり、類似操作を見つける可能性も高くなります。多数のパラメーターを持つ操作は数個の操作に分ける必要がある場合があります。操作は、使用する人が理解できるようにしなければなりません。簡略な説明として以下のようなものがあります。
    • パラメーターの意味。名前から類推できない場合
    • パラメーターの受け渡しが値によるもの参照によるもの
    • 値を与えておくべきパラメーター
    • オプションにできるパラメーターと、値が与えられない場合のパラメーターのデフォルト値
    • パラメーターの有効範囲。適用可能な場合
    • 操作で行われること
    • 参照によるパラメーターの中でどれが操作で変更されるか

操作の定義が完了すると、各メッセージに対してどの操作が呼び出されるかという情報を付けてシーケンス図を完成させます。

詳しくは、『ガイドライン: 設計クラス』の『クラス操作 』を参照してください。

操作の可視性の定義

操作ごとに、操作のエクスポートの可視性を以下から選択して定めます。

  • public - 操作は、そのクラス以外のモデル要素からも見えます。
  • implementation - 操作は、そのクラスの内部でのみ見えます。
  • protected - 操作は、そのクラス、サブクラス、あるいはクラスのフレンド のみに見えます (言語依存)。
  • private - 操作は、そのクラスとクラスのフレンド のみに見えます。

操作の目的を達成できて、しかも最も可視性を制限できるものを選びます。こうするには、シーケンス図を見て、各メッセージに対して、それが受け手のパッケージの外部のクラスから (public レベルの可視性が必要)、パッケージの内部から (implementation レベルの可視性が必要)、サブクラスから (protected レベルの可視性が必要)、クラス自体または <<friend>> から (private レベルの可視性が必要) 送られるのかを決定します。

クラス操作の定義

ほとんどの場合、操作はインスタンス操作で、クラスのインスタンスに対して実行します。ただし、場合によっては、操作はクラスの全インスタンスに適用され、クラス範囲の操作となります。クラス操作の受け手は、実際には、クラスの特定のインスタンスというよりは、クラス自体の説明であるメタクラスのインスタンスです。クラス操作の例としては、新インスタンスを生成する (インスタンス化する) メッセージがあり、クラス allInstances などを戻します。

クラス範囲の操作を表すには、操作の文字列に下線を施します。

メソッドの定義ページの先頭へ

メソッドは操作の実装を指定します。多くの場合、操作で必要となる振る舞いは操作名、説明およびパラメーターで十分に定義でき、メソッドはプログラミング言語で直接実装します。操作の実装に特別なアルゴリズムが必要な場合、あるいは操作の記述に示されている以上の情報が必要な場合は、別個にメソッドの記述が必要です。このメソッドでは、操作が単に何をするかだけでなく、どのようにして動作するかを記述します。

記述がある場合、メソッドは以下を説明しなければなりません。

  • 操作の実装方法
  • 操作実装のための属性の実装および使用方法
  • 操作実装のための関係の実装および使用方法

要求はケースバイケースで異なりますが、クラスのメソッド仕様は常に以下を定めます。

  • 要求に応じて何を行うか
  • 他にどのようなオブジェクトと操作を使うか

より具体的な要求としては、次のようなものがあります。

  • パラメーターの実装方法
  • 存在する場合は使用する特殊なアルゴリズム

このような情報に対して、シーケンス図は重要な情報源となります。これらのダイアグラムから操作を実行する場合に、他のオブジェクトで何の操作が使用されるのかが明らかになります。操作を完全に実装するには、他のオブジェクトでどの操作が必要になるのかという仕様が必要となります。完全なメソッド仕様の作成には、関連するオブジェクト向けの操作の識別および対応するシーケンス図の検査が必要です。

状態の定義 ページの先頭へ

ある種の操作に対しては、操作の振る舞いは受信者のオブジェクトの状態に依存しています。状態マシンはオブジェクトが取り得る状態を説明するツールであり、オブジェクトをある状態から別の状態へ遷移させるイベントを説明するツールです。これについては、『ガイドライン: ステートチャート図』を参照してください。状態マシンは、アクティブ・クラスの説明に最も役立ちます。

単純な状態マシンの例を図 2 に示します。

付随するテキスト内で説明される図

図 2: 給油機に関する単純なステートチャート図

各遷移イベントは操作と関連付けることができます。オブジェクトの状態に応じて、操作は異なる振る舞いをします。遷移イベントでは、それがどのように起きるのかを記述します。

関連操作に対するメソッドの記述は状態特有の情報で更新すべきで、各々の適切な状態に対して、操作で何をすべきかを示します。状態を表現するために属性がよく使われます。ステートチャート図は属性の識別ステップへの入力として役立ちます。

詳細は、『ガイドライン: ステートチャート図』を参照してください。

属性の定義 ページの先頭へ

メソッドの定義および状態の識別時に、操作の実行のためにクラスが必要とする属性を明確にします。属性はクラス・インスタンス用の情報記憶であり、クラス・インスタンスの状態を表すのによく使用されます。クラス自体が保持する情報は、属性によって保持されます。 各属性について以下を定義します。

  • 属性の名前: これは実装言語とプロジェクトの両方の命名規約に従ってください
  • 属性の: これは実装言語がサポートする基本的なデータ型です
  • デフォルト値あるいは初期値: クラスの新しいインスタンスを作成した場合には、この値に初期化します
  • 属性の可視性: 次の値のいずれかになります
    • public: 属性は、クラスを含むパッケージの内側からも外側からも見えます
    • protected: 属性は、そのクラス、サブクラス、あるいはこのクラスのフレンドのみに見えます (言語依存)
    • private: 属性は、クラス自体およびクラスのフレンドから見えます
    • implementation: 属性は、そのクラスのみに見えます
  • 永続的クラスの場合、この属性が永続的 (デフォルト) か一時的か。クラス自体が永続的であっても、クラスのすべての属性が永続的である必要はありません。

全属性が必要かどうかを明確にします。属性はその正当性を確かめておくべきです。属性をプロセスの初期段階で追加したものの、近視眼的であったために不必要になってもその属性が依然として存在し続けることが簡単に発生します。余分な属性がインスタンスの数千倍または数百万倍に増えると、システムの性能と記憶領域要求に有害な影響を与えます。

詳しくは『ガイドライン: 設計クラス』の『属性 』の項を参照してください。

依存関係の定義 ページの先頭へ

オブジェクト間で通信が必要なケースでは、次の質問をしてください。

  • 受け手への参照は操作に対するパラメーターとして渡されますか。 そうである場合には、その送り手と受け手のクラスを含むクラス図で、それらの間に依存関係を確立します。さらに、相互作用を示すフォーマットとしてコミュニケーション図を使用している場合は、リンクの可視性をパラメーターに設定します。
  • 受け手はグローバルですか。 そうである場合には、その送り手と受け手のクラスを含むクラス図で、それらの間に依存関係を確立します。 さらに、相互作用を示すフォーマットとしてコミュニケーション図を使用している場合は、リンクの可視性をグローバルに設定します。
  • 受け手は操作中に作成され、廃棄される一時的なオブジェクトですか。 そうである場合には、その送り手と受け手のクラスを含むクラス図で、それらの間に依存関係を確立します。 さらに、相互作用を示すフォーマットとしてコミュニケーション図を使用している場合は、リンクの可視性をローカルに設定します。

この方法でモデル化したリンクは一時的なリンクで、コラボレーションという特定のコンテキストの中で限られた時間しか存在しません。その意味では、それらはコラボレーションの関連ロールのインスタンスです。一方、クラス・モデル内の関係 (つまり、コンテキストから独立した関係) は、前述のとおり、依存関係です。『RUM98』で述べられている一時的なリンクの定義は、次のとおりです。「そのようなリンクすべてを関連としてモデル化することはできますが、関連に対する条件を幅広く記述することが必要です。そうしないと、オブジェクトの組み合わせを制限する際にリンクの精度が大部分失われます。」 このような状況では、依存関係のモデル化は、コラボレーション内の関係のモデル化ほど重要ではありません。それは、依存関係では関係を完全に記述できず、関係が存在することしか記述できないからです。

関連の定義 ページの先頭へ

関連は、オブジェクトが相互にやりとりする仕組みを実現します。 メッセージが流れる通路をオブジェクトに提供します。また、クラス間の依存関係を文書化し、ある 1 つのクラスの変更を他の多数のクラスで認識できることを強調します。

各操作に対するメソッドの記述を調べ、クラスのインスタンスが他のオブジェクトとどのようにやりとりし、連携動作するのかを理解します。他のオブジェクトにメッセージを送るためには、オブジェクトにメッセージの受け手への参照が含まれている必要があります。コミュニケーション図 (シーケンス図の代替) では、図 3 に示すように、リンク形式でオブジェクトのやりとりを示します。

付随するテキスト内で説明される図

図 3: コミュニケーション図の例

関連と集約の定義

残りのメッセージでは、関連または集約を使い、やりとりする 2 つのクラスのインスタンス間の関係を指定します。 適切な表現手段を選択するためには『ガイドライン: 関連』および『ガイドライン: 集約』を参照してください。 この両方の関係について、コミュニケーション図のリンクの可視性をフィールドに設定します。その他の作業としては、次のものがあります。

  • 関連と集約のナビゲーション性を確立します。これは、相互作用図でリンク付けを行うのにどのようなナビゲーション性が必要かを検討することにより実行できます。ナビゲーション性はデフォルトでになっているので、関連内のクラスに含まれる全オブジェクトの逆方向リンクのロールがすべて、ナビゲーション性を必要としない関連 (および集約) になっているものを探すだけで済みます。その場合には、クラスのロールのナビゲーション性をに設定します。
  • 関連クラスとして表す関連自体に属性がある場合は、関連クラスに相当する設計クラスを作成し、適切な属性を付与します。関連クラスと他の 2 つのクラスの間に適切な多重度を持つ関連を確立し、他の 2 つのクラスの間にこの関連クラスを挟み込みます。
  • 関連端整列させるかどうかを指定します。これは関連の一端にあるオブジェクトと関連するオブジェクトが、保持すべき整列性を有している場合に該当します。
  • 関連 (あるいは集約) するクラスが現在のクラスだけから参照される場合は、クラスをネストすべきかどうかを検討します。クラスをネストする利点としては、メッセージ処理が高速になることと設計モデルが単純になることがあげられます。欠点としては、ネストされたクラスのインスタンスの有無にかかわらず、ネストされたクラス用に静的に割り当てたスペースが存在していること、包含するクラスで識別する以外にオブジェクトの識別方法がなくなってしまうこと、また、包含するクラスの外部から内部のネストされたクラスのインスタンスを参照できなくなることです。

関連と集約は、関連するクラスを表すクラス図で定義することが最適です。クラス図は関連するクラスを含むパッケージで所有すべきです。図 4 は関連と集約を明記したクラス図の例を示しています。

付随するテキスト内で説明される図

図 4: クラス間の関連、集約、汎化を表すクラス図の例

分析クラス間の通知予約関係の処理

分析クラス間の通知予約関係は、クラス間のイベント依存関係を明確にするために使います。設計モデルでは、既存のイベント・ハンドラー・フレームワークを使うか、独自のイベント・ハンドラー・フレームワークを設計および作成し、このようなイベント依存関係を明示的に処理する必要があります。Visual Basic のようなプログラミング言語では、対応するイベントを素直に宣言、発生、処理できます。その他の言語では、再利用可能な関数のライブラリーを追加して、通知予約とイベントを処理する必要があります。この機能を購入できない場合は、設計して作成する必要が生じます。『ガイドライン: 通知予約関係』も参照してください。

内部構造の定義 ページの先頭へ

クラスの中には、複雑な抽象化/抽象概念を表し、複雑な構造を持つものもあります。 クラスをモデリングする際に、設計者は、内部に含まれる要素とそれらの関係を表現し、 それに従って実装担当者が該当クラス内で生じるコラボレーションを確実に実装できるようにしたい場合があります。

UML 2.0 では、クラスは内部構造や複数のポートを持つことができる構造化 されたクラスとして定義されています。そして、 クラスは、接続されたパートの集合や、さらに細かい単位に分解できる場合もあります。クラスをカプセル化し、外部からのコミュニケーションが宣言済みのインターフェースに従うポートを必ず経由するようにすることもできます。

複雑な構造を持つ複雑なクラスがある場合、該当クラス用の複合構造図を作成します。該当クラスの振る舞いに対応する役割を実行するパートをモデリングしてください。コネクターによってどのようにパートを「結び付ける」かを定義します。 該当クラスの別のクライアントが、そのクラスが提供する振る舞いの特定の一部にアクセスできるようにする場合は、ポートと宣言済みのインターフェースを使用してください。また、該当クラスの内部のパートを環境から完全に隔離する目的でも、ポートを利用します。

このトピックの詳細と複合構造図の例については、『概念: 構造化されたクラス』を参照してください。

汎化の定義 ページの先頭へ

クラスは、共通の振る舞いと構造を反映した汎化階層に編成される場合があります。共通のスーパークラスを定義し、サブクラスにスーパークラスの振る舞いと構造の両方を継承させることができます。 汎化は表記法上の便宜を図るもので、ある 1 箇所で共通の構造と振る舞いを定義すると、定義したものをその振る舞いと構造が繰り返される場所で再利用できます。汎化関係の詳細については、『ガイドライン: 汎化』を参照してください。

汎化できるものが見つかったら、共通の属性、関連、集約および操作を含む共通のスーパークラスを作成します。共通のスーパークラスのサブクラスになるクラスから、共通の振る舞いを取り除きます。サブクラスからスーパークラスへの汎化関係を定義します。

ユース・ケースの競合の解決 ページの先頭へ

この手順の目的は、複数のユース・ケースが設計クラスのインスタンス群に潜在的に、一貫しない方法で同時にアクセスする場合に、並行アクセスの衝突を防ぐことです。

ユース・ケース単位で設計プロセスを進めていく上で問題となることの 1 つに、2 つ以上のユース・ケースが、潜在的に衝突する方法で設計オブジェクト上の操作を、同時に呼び出そうとすることが挙げられます。このような場合には、並行性の衝突を明確にし、明白に解決する必要があります。

同期メッセージ処理を利用すると、操作を実行してもその操作が完了するまで、オブジェクトに対する次の呼び出しは実行されません。同期メッセージ処理とは、メッセージを先着順で処理することを意味します。これにより、特に全メッセージが同一の優先度を持っていたり、同一の実行スレッドで動作したりする場合に、並行性の衝突を解決できます。1 つのオブジェクトが異なる実行スレッド (アクティブ・クラス) からアクセスされる場合は、明白なメカニズムを使って、並行性の衝突を防ぐ、または解決する必要があります。

同一オブジェクトに対する異なる操作を、並行性の衝突を引き起こさずに異なる実行スレッドにより同時に呼び出せる場合があります。つまり、顧客の名前も住所も、衝突を引き起さずに並行に変更できます。このようなことが可能なのは、衝突が発生するオブジェクトの同一プロパティーを 2 つの異なる実行スレッドが変更しようとする場合のみです。

異なる実行スレッドから並行にアクセスされる可能性がある各オブジェクトについて、同時アクセスから保護する必要があるコード部分を明確にします。推敲フェーズの初期には、特定のコード部分を明確にするのは不可能です。保護すべき操作だけで十分です。次に、衝突を起こす同時アクセスを防止する適切なアクセス制御メカニズムを選択あるいは設計します。このようなメカニズムの例としては、アクセスを順次行うためのメッセージのキューイング、セマフォーあるいはトークンを使った 1 度に 1 スレッドのアクセス制限、その他のロック・メカニズムなどがあります。このメカニズムの選択は、実装に大きく依存し、通常、プログラミング言語と操作環境によって異なります。

機能外要求の処理一般 ページの先頭へ

設計クラスは、 このステップへの重要な入力は分析クラスに対する機能外要求であり、これは、特殊な要求と責任の中で既に述べられています。このような要求は、クラスの実現にどのようなアーキテクチャー (分析) メカニズムが必要かという観点で指定される場合がよくあります。このステップではクラスを改善し、このような分析メカニズムに対応する設計メカニズムを組み込みます。

利用可能な設計メカニズムは、 必要とする各設計メカニズムに対して、できるだけ多数の特徴を付加し、適切な範囲を定義します。設計メカニズムの詳細については、『作業: 設計メカニズムの識別』、『概念: 分析メカニズム』、および『概念: 設計メカニズムと実装メカニズム』を参照してください。

クラスを設計する際に考慮しておくべき、いくつかの一般的な設計ガイドラインと設計メカニズムを示します。

  • 既存の製品とコンポーネントを利用する
  • プログラミング言語に適応する
  • オブジェクトを分散させる
  • 受け入れ可能な性能を実現する
  • 一定のセキュリティー・レベルを実現する
  • エラーを処理する
  • その他

結果の評価 ページの先頭へ

この段階で設計モデルをチェックして、作業が正しい方向に進んでいるか確認します。詳細にレビューする必要はありませんが、以下のチェックポイントを考慮しなければなりません。



Rational Unified Process   2003.06.15