オブジェクト指向プログラミング(4) 静的分析(2) 第6回 ソフトウエアの再利用 オブジェクト指向プログラミング(4) 静的分析(2)
関連 オブジェクト指向のプログラム ・クラスがクラスを操作し、そして、そのクラスがまた別のクラスを操作する、というように動いていきます。 オブジェクト指向のプログラム ・クラスがクラスを操作し、そして、そのクラスがまた別のクラスを操作する、というように動いていきます。 ・なんらかの操作の関係があるようなクラス同士を、「そのクラス間に関連がある」と表現します。
関連の分析とその表記 「関連」はオブジェクト指向において、非常に重要な概念である。 クラス自体の分析以上に、関連の分析が重要である。 クラス図では、関連を図のように表します。 このクラス間にどのようなやり取りがあるのかということを表現するためのもの
関連名は一般的に動詞で、その間でやり取りされる代表的な操作の名前が使用される。 関連の表記 担任する 関連名は一般的に動詞で、その間でやり取りされる代表的な操作の名前が使用される。 発射する
関連と属性の違い 社員クラスを考え見よう 属性というものがあくまでも、クラスそのもの自体の特徴。 そのクラスの本質的な特徴でないものについては「関連」である場合が多い。
関連と属性の違い この例の「所属課」について考えみよう 名詞「ここでは課」から、それに対するクラス候補が認識できる。
多重度 関連には、多重度といわれる概念が存在する。 たとえば、生徒と教師を考えた場合、必ずしも1対1でなく、1人の教師が複数の生徒を担任するということが言える。 これを「教師と生徒は1対多関連である」という。 クラス間の量的な対応関係を「多重度」と呼び ます。
多重度 多重度を加えたクラス図 担任する
多重度 対応する数による表現方法の変化 相手が1 相手が0以上の複数 相手が0か1 4 相手が定数(例:4) 2-4 相手が2~4
多重度 関連の種類 1対1 1対多 多対多
多重度 多対多の関連の例 講師は講義で、複数の生徒に対して教える。そして、生徒は1日に複数の講義を受講することによって、複数の教師に教えられる。 担任する
ロール(役割) ロールはクラスが相手のクラスに対してどのような位置付けであるか、ということを記述するものです。 生徒 担任する
関連のクラス化 関連自体が、あるときクラスのように属性や操作を持つ、オブジェクト指向概念 所属する
関連の実装 「関連を実装する」ということは、「その相手インスタンスにアクセスする方法を実現する」ということになります。
関連先が単数の場合 クラスのメンバに相手クラスのポインタを持つということで実際に関連を張る 実際のコードで示してみましょう。
関連をコードとして実装した例 class Tank // 戦車クラス { Missile * missile ; // ミサイルクラスとの関連 public : virtual void shoot () ; // 発射メンバ関数 virtual void setMissile ( Missile * pmissile ) { // ミサイルクラスインスタンス設定 missile = pmissile ; } } ; void Tank :: shoot () // 発射メンバ関数の実装 missile -> fire () ; // ミサイル発射 void Foo :: bar () // 実際の使用例 Tank tank ; // 戦車インスタンス生成 Missile * missile ; // ミサイルクラスのポインタ missile = new Missile ; // ミサイルインスタンス生成 tank . setMissile ( missile ) ; // ミサイルインスタンス設定 : tank . shoot () ; // ミサイル発射 delete missile ; // デストラクト
関連先が複数の場合 関連先が複数の場合は、ポインタの配列を使用すれば実現できる。 実際のコードで示してみましょう。
関連先が複数の場合を実装 LIST5-2:関連先が複数の場合をポインタの配列によって実装 class Teacher // 教師クラス { // 担当している生徒インスタンスのポインタ Person * students [ 100 ] ; public : virtual void printName () ; // 担当している生徒一覧出力 virtual void setStudent ( Person * pstudent , int num ) { // 生徒インスタンス設定 students [ num ] = pstudent ; } } ; void Teacher :: printName () { // 生徒一覧表示のメンバ関数 int i ; for ( i = 0 ; students [ i ] != NULL ; i ++ ) { // ポインタが設定されているとき // 名前を取得して表示 puts ( students [ i ] -> getName () ) ;
単方向関連、双方向関連 基本的に、関連は双方向。(分析段階) 双方向関連は、お互いにポインタを持ち合うように実装する。 しかし、実際は、単方向関連が多い。
クラス図を完成してみよう 前回、操作と属性を分析するときの順序関係で、「操作が属性よりも先」と言いました。 関連を加えた上で、再度順序関係を考えると以下のようになる。
クラス図を完成してみよう 分析の順序 ①クラスの洗い出し ②関連の探索 ③操作の洗い出し ④属性の洗い出し