平成26年秋期試験午後問題 問5

午前試験免除制度対応!基本情報技術者試験のeラーニング【独習ゼミ】

問5 ソフトウェア設計

共通ライブラリのオブジェクト指向設計に関する次の記述を読んで,設問1,2に答えよ。

 システムインテグレータのT社は,自社で開発するソフトウェアの品質の安定化,開発の生産性の向上などを目的として,オブジェクト指向を用いた共通ライブラリの設計に取り組んでいる。
 これまでT社では,システム開発において社員検索機能を数多く開発してきた。この機能は,組織情報から特定の社員を探すために使用される。図1に示すように 左側に階層表示されている組織の一つを選択すると,右側にその組織に属する社員及び下位の 組織の情報が表示されるので,目的とする社員が見つかるまで下位の組織を選択して検索する。図1は,左側で金融システム部を選択し,右側に金融システム部に属する社員及び下位の組織を表示している例である。
 T社では,この組織の階層構造情報(以下,組織階層という)を,デスクトップアプリケーションソフトウェア,Webページなどのユーザインタフェースに出力するシステムを開発してきた。
pm05_1.png
 組織階層の扱いは,どの開発プロジェクトにおいても類似するものが多い。そこで,組織階層を扱う機能をユーザインタフェースから切り離して,様々な開発プロジェクトで再利用できるように,共通ライブラリとして設計することにした。共通ライブラリは,オブジェクト指向で設計し,UMLのクラス図で表現する。ここで,共通ライブラリの設計に当たり,共通ライブラリを利用する側のソフトウェアを一律にクライアントと呼ぶことにする。
 まず,分析のためのクラス図を作成した。

〔分析のためのクラス図の説明〕
 組織階層において,ある組織が親の組織(以下,親組織という)をもつ場合,親組織は必ず一つであり,子の組織(以下,子組織という)をもつ場合,子組織の数に制限はない。また,親組織をもたない組織,子組織をもたない組織,親組織も子組織ももたない組織もある。社員は必ず一つの組織だけに属する。
  • 組織階層は木構造で管理する。
  • クライアントが組織階層を参照する際,組織と社員を共通に扱えるようにするために,どちらも組織エントリとして管理する。
 図2は,分析のためのクラス図である。
pm05_2.png
 次に,組織エントリを管理するクラスの,設計のためのクラス図を作成した。

〔設計のためのクラス図の説明〕
 組織は自身に属する組織エントリのリスト(以下,組織エントリリストという)を属性として保持する。
 この組織エントリリストを設計するためのクラス図を図3に,組織エントリリストに定義する属性と操作の説明を表1に示す。以下,操作をメソッドという。
  • 組織エントリリストは,組織エントリをサイズが可変の配列で管理する。
  • クライアントは,組織エントリリストに表1のメソッドでアクセス(組織エントリの追加や削除,取出し,走査など)する。
pm05_3.png

設問1

図2の分析のためのクラス図の中の に入れる正しい答えを,解答群の中から選べ。
a,b に関する解答群
  • 親組織
  • クライアント
  • 子組織
  • 社員
  • 組織
  • 組織エントリ
  • 組織階層
c,d に関する解答群
  • 0
  • 0..1
  • 0..*
  • 1
  • 1..*
解答選択欄
  • a:
  • b:
  • c:
  • d:
  • a=
  • b=
  • c=
  • d=

解説

aについて〕
このクラスは、下位の2つのクラスの上位クラスに当たるものです。〔分析のためのクラス図の説明〕(2)には、「組織と社員を共通に扱えるようにするために,どちらも組織エントリとして管理する」とあるように、組織と社員どちらの組織エントリとして扱えるようになっている必要があります。このため、組織エントリという親クラス(上位クラス)で、組織と社員に共通の属性・メソッドを定義し、組織および社員の固有の属性・メソッドは組織エントリクラスを継承した子クラス(下位クラス)で定義することになります。

したがって、上位クラスの名称は「組織エントリ」が適切です。

a=カ:組織エントリ

bについて〕
前述のように、組織エントリクラスの下位クラス2つは、社員クラスと組織クラスです。[b]は、組織エントリクラス(社員・組織)と集約関係にあり、組織エントリクラスが[b]クラスの部分であることを示しています。つまり、[b]クラスは幾つかの組織エントリクラスを持つということです。組織階層は親子関係(木構造)であり、社員と組織(組織エントリ)は親組織に属するので、[b]は組織クラスとなります。

b=オ:組織

cについて〕
組織クラスのインスタンスから見た組織エントリクラスのインスタンスの多重度が入ります。ここでは、組織エントリクラスを、社員クラスと組織クラスをまとめたものとして考えると良いでしょう。

多重度をざっくり言うと、組織クラスのインスタンスが生成された場合、クラス内部に幾つの組織エントリクラスを持ち得るのかということです。〔分析のためのクラス図の説明〕を読むと、
  • 組織が子組織を持つ場合、子組織(エントリ)の数に制限はない
    →上限はなし(*)
  • 子組織(エントリ)をもたない組織もある
    →下限は0
とわかるため、[c]には「0..*」が入ります。

c=ウ:0..*

dについて〕
組織エントリクラスのインスタンスから見た組織クラスのインスタンスの多重度が入ります。

〔分析のためのクラス図の説明〕を読むと、
  • 親組織は必ず一つ、社員は必ず一つの組織に属する
    →上限は1
  • 親組織を持たない組織もある
    →下限は0
とわかるため、[d]には「0..1」が入ります。

d=イ:0..1

設問2

次の記述中の に入れる適切な答えを,解答群の中から選べ。

 共通ライブラリの社内レビューを実施したところ,組織エントリリストのクラス設計に対して次の指摘が挙がった。

〔指摘の内容〕
 組織エントリリストから組織エントリを取り出すとき,クライアントが要素番号を指定する必要がある。全ての組織エントリを取り出すときや,特定条件を満たす組織エントリだけを取り出したいときなど,クライアント側の実装依存が大きくなる。図4にクライアントの走査の例を示す。
pm05_4.png
 共通ライブラリは,組織エントリリストの内部構造をクライアントに意識させず,組織エントリリストの走査を拡張できるように改善すべきである。

 この指摘を受け,組織エントリリストのクラス設計を次の設計方針に従って見直すことにした。

〔設計方針〕
  • 組織エントリリストは,より汎用的にするために,任意のオブジェクトを管理できるようにする。
  • リストを走査する処理は,別のクラス(以下,イテレータという)に与える。リストでは,このイテレータを生成してeをイテレータに登録することでイテレータがリストを走査できるようにする。
  • 共通ライブラリで提供するイテレータは,先頭から順に全ての要素を 走査するメソッドを提供する。
  • アクセス方法の統一を目的として,必要なメソッドをインタフェースとして定義する。クライアントは,必ずこのインタフェースを用いてリストを走査することとする。
  • クライアントは,共通ライブラリで提供するメソッドと異なる走査をしたい場合は,fする。
 図5は見直し後の設計のためのクラス図,表2は図5のクラス図の説明である。
pm05_5.png
e に関する解答群
  • クライアント
  • 属性
  • メソッド
  • リスト自身
f に関する解答群
  • BaseList と Baselterator を継承して処理をオーバーライド
  • BaseList と Baselterator を継承してメソッドを追加
  • BaseList と Baselterator を実装して処理をオーバーライド
  • BaseList と Baselterator を実装してメソッドを追加
  • List と Iterator を継承して処理をオーバーライド
  • List と Iterator を継承してメソッドを追加
  • List と Iterator を実装して処理をオーバーライド
  • List と Iterator を実装してメソッドを追加
解答選択欄
  • e:
  • f:
  • e=
  • f=

解説

eについて〕
図5を見ると、イテレータを実装したクラスは内部に走査対象のリストである list という属性を持ち、この list に対して走査を行います。イテレータのクラスは汎用的に作られており、様々なオブジェクトを走査できるようになっています。よって、組織エントリリストのクラスからイテレータを実装したクラスを生成する際、操作対象のリストとして生成元であるリスト自身(this や self)を登録しなければなりません。

e=エ:リスト自身

fについて〕
まず、クラスは継承するもの、インタフェースは実装するものですので「クラスを実装」「インタフェースを継承」としている「ウ」「エ」「オ」「カ」は不適切であるとわかります。

次に、「クライアントは,必ずこのインタフェースを用いてリストを走査することとする」という条件があるため、走査内容は変わってもメソッド名は同じに保たなくてはなりません。この点で「メソッドを追加する」としている「イ」と「ク」は不適切です。

最後に残った「ア」と「キ」ですが、オーバーライドは上位クラスで定義済のメソッドを再定義することですから、メソッドの型だけが記述され具体的な処理内容が記述されていないインタフェースのメソッドをオーバーライドすることはできません。この点で「キ」は不適切です。

したがって「ア」が適切となります。

例えば、後方から順に走査するようにしたければ、BaseIterator を継承したクラスで first、isDone 及び currentItem を次のようにオーバーライドします。
first
currentPosition を末尾に移動する
isDone
currentPosition が先頭より前に達したら false、そうでなければ true を返す
currentItem
currentPosition の要素をクライアントに返した後、currentPosition を先頭方向に1つ移動する
そして、BaseList クラスを継承したクラスを作成し、生成するイテレータのクラスを BaseIterator を継承したクラスに変更することになります。

f=ア:BaseList と Baselterator を継承して処理をオーバーライド

Pagetop