応用情報技術者 2024年 春期 午後 問08
ダッシュボードの設計に関する次の記述を読んで、設問に答えよ。
Y社は、食品などを販売する店舗を経営する企業である。複数ある店舗では、商品の販売状況や在庫状況に合わせて、割引率を設定したり、店舗間で在庫の移動を行ったりしている。販売に関する情報は販売管理システムで管理しているが、状況をリアルタイムで監視するには不向きであった。そこで、販売状況をリアルタイムで監視できるシステム〔以下、ダッシュボードという〕を開発することにした。
Y社では、商品ごとに商品分類を設定し、売上金額や販売数の集計に利用している。Y社が扱う情報のデータモデル〔抜粋〕を図1に、ダッシュボードのイメージ〔一部〕を図2に示す。


販売状況や在庫状況はデータベースで管理する。データベースに新たな販売実績が追加されたり、在庫数が更新されたりすると、その内容がダッシュボードに随時反映され、最新の情報が表示される。
Y社は、ダッシュボードの開発をX社に依頼し、Z社はその設計に取り掛かった。
〔ダッシュボードのクラスの設計〕
Z社は、ダッシュボードのクラスの設計を行った。設計したクラス図を図3に、表示できるグラフの種類を表1に、主なクラスの説明を表2に示す。Controllerクラスは、システム全体の挙動を制御するクラスである。Viewクラスは、画面にグラフを表示する機能をもつクラスである。グラフには複数の種類があるので、その種類ごとに、Viewクラスをaしたクラスを作成する。Subjectクラスは、データベースが更新されたことをViewクラスのオブジェクトに通知するクラスである。図1のデータモデル中のテーブルのうち、ダッシュボードで監視したい情報に関するテーブルのそれぞれについて、Subjectクラスをaしたクラスを作成する。以下、Viewクラス、Subjectクラスをaしたクラスのオブジェクトを、それぞれViewオブジェクト、Subjectオブジェクトという。



〔グラフの新規表示〕
例えば、“時間帯ごと商品分類ごとの売上金額”のグラフを新たに画面上に表示する場合を考える。グラフの種類は棒グラフなので、棒グラフ View クラスのオブジェクトを作成する。次に、①関係する Subject オブジェクトの addObserver メソッドを呼び出す。その後、画面の初期表示のために、画面表示更新メソッドを呼び出す。
〔グラフの表示内容更新〕
店舗で商品が販売されると、販売管理システムが、データベースにレコードを追加する。そのとき、ダッシュボードの Controller クラスに実装されている dbUpdated メソッドが呼び出されるように、システム間の連携が行われている。
Controller クラスは、dbUpdated メソッドが呼び出されると、更新されたテーブルに対応する Subject オブジェクトの notifyObservers メソッドを呼び出す。
notifyObservers メソッドは、そのオブジェクトが属性としてもつ配列 views に格納されている全ての View オブジェクトの notify メソッドを呼び出す。notify メソッドは、画面表示更新メソッドを呼び出す。View クラスの画面表示更新メソッドはdメソッドなので、例えば、“時間帯ごと商品分類ごとの売上金額”の場合はeクラスに実装されたメソッドを呼び出す。
〔データのフィルタリング〕
Y社からの追加の要求で、集計結果をフィルタリングする機能を追加することになった。例えば、“時間帯ごと商品分類ごとの売上金額”のグラフ上で、特定の商品分類の表示箇所をマウスでクリックしたときに、表示されている全てのグラフについて、指定した商品分類で絞り込んだ結果を表示したい。そこで、絞込条件を取り扱うクラスとして絞込条件クラスを導入し、次の改修を加えることで機能を実現することにした。
・絞込条件クラスは、属性として“テーブル名”、“項目名”、“絞込条件の値”をもつ。
例えば、商品分類で絞り込む場合は、テーブル名に“商品マスタ”、項目名に“商品分類コード”、絞込条件の値に“商品分類コードの値”が入る。
・Controller クラスの属性に絞込条件クラスのオブジェクトを追加し、その属性に条件を設定するための setFilter メソッドを追加する。
・View オブジェクトが画面の表示を更新する際に、絞込条件のオブジェクトが引き渡されるようにするために、Subject クラスの notifyObservers メソッドと、Viewクラスの notify メソッドのそれぞれについて、呼出しの②仕様を変更する。
・集計処理クラスの処理で絞込条件を考慮して集計し、画面を更新する。
画面の操作が行われたら、View オブジェクトが絞込条件オブジェクトを生成し、Controller オブジェクトの setFilter メソッドを呼び出す。その後、全ての Viewオブジェクトの画面表示更新メソッドを呼び出すことで、機能を実現する。
〔過負荷の回避〕
設計レビューを実施したところ、次の点が指摘された。
・販売管理システムが、データベースに販売実績のレコードを連続で追加すると、ダッシュボードが過負荷になるおそれがある。
・一つの View オブジェクトはfで、1回の販売実績の登録で、表示の更新が複数回発生してしまう。
そこで、View クラスの属性に“更新フラグ”を追加し、notify メソッドでは画面表示更新メソッドを呼び出すのではなく、“更新フラグ”を立てるようにした。また、“更新フラグ”を立てる処理とは別に、定期的に画面表示更新メソッドを呼び出す仕組みを用意し、“更新フラグ”が立っている場合だけ画面の更新処理を実行してから“更新フラグ”を降ろすようにした。
設問1:
本文中のaに入れる適切な字句を答えよ。
模範解答
a:継承
解説
解答の論理構成
- 問題文では「グラフには複数の種類があるので、その種類ごとに、Viewクラスをaしたクラスを作成する」と述べています。ここで**「複数種類のグラフ」**という要件をクラス図で実装する一般的な方法は、共通部分を基底クラスにまとめ、個別の振る舞いを派生クラスで実装することです。
- 同じ段落で「図1のデータモデル中のテーブルのうち、ダッシュボードで監視したい情報に関するテーブルのそれぞれについて、Subjectクラスをaしたクラスを作成する」とも指示しています。つまり**「テーブル数だけ Subject の派生クラスを用意する」**という方針です。
- 以上2か所とも「基底クラスの設計を土台に派生クラスを作る」という文脈で使われているため、a には「継承」を入れるのが自然な流れです。
- 図3 のクラス図でも、Subject から 販売実績Subject, 在庫Subject, 販売明細Subject へ、さらに View から 棒グラフView, 折れ線グラフView, 円グラフView へと「→」で接続され、その凡例に「継承(c)」と記されています。ここでも継承関係であることが補強されています。
以上より、a に入る字句は「継承」です。
誤りやすいポイント
- 「実装」や「拡張」と回答してしまう
→ 派生クラスを作る目的は機能追加ではなく型階層を構成することなので適切でありません。 - 集約(HAS-A)と継承(IS-A)の混同
→ Subject が View を配列で保持する部分は集約ですが、ここで問われているのは型の派生です。 - デザインパターン名(Observer 等)を書いてしまう
→ 問題は字句を問うており、パターン名は解答になりません。
FAQ
Q: 「多重度 1 0..*」の線を継承と誤認しました。判断基準は?
A: 線の形状に注目してください。図3 の凡例では「→ 継承」と明記され、白抜き三角矢印で表現されています。菱形(◇/◆)は集約・コンポジションです。
A: 線の形状に注目してください。図3 の凡例では「→ 継承」と明記され、白抜き三角矢印で表現されています。菱形(◇/◆)は集約・コンポジションです。
Q: なぜ抽象クラスではなく継承そのものが解答なのですか?
A: 文中で直接「Viewクラスをaしたクラス」「Subjectクラスをaしたクラス」と、動詞としての “継承したクラス” が要求されているため、語句は「継承」が最も適合します。
A: 文中で直接「Viewクラスをaしたクラス」「Subjectクラスをaしたクラス」と、動詞としての “継承したクラス” が要求されているため、語句は「継承」が最も適合します。
Q: 派生クラスをたくさん作るとクラス数が増えませんか?
A: YES ですが、各テーブル・各グラフタイプごとに固有ロジックが存在し、**SRP(単一責任の原則)**を守る設計と考えれば妥当です。
A: YES ですが、各テーブル・各グラフタイプごとに固有ロジックが存在し、**SRP(単一責任の原則)**を守る設計と考えれば妥当です。
関連キーワード: 継承, 抽象クラス, オブザーバパターン, 集約関係, クラス図
設問2:
図3中のb、cに入れる適切なクラス間の関係又は多重度を答え、クラス図を完成させよ。なお、表記は図3の凡例に倣うこと。
模範解答
b:0..*
c:⇧
解説
解答の論理構成
-
Subject―View 間の多重度 b
- 【問題文】には「Subjectクラスは、データの更新をViewオブジェクトに通知するクラス。通知先は、addObserverメソッドで登録する。notifyObserversメソッドは、登録された全ての通知先のnotifyメソッドを呼び出す。」とあります。
- 「登録された全ての通知先」という表現は、Subject 1つに対して View が複数存在し得ることを示します。さらに、View が未登録の状態(0件)も成立するため、View 側の多重度は “0個以上” が適切です。
- よって b には「0..*」が入ります。
-
c に入るクラス間関係(矢印種別)
- 【問題文】には「図1のデータモデル中のテーブルのうち、ダッシュボードで監視したい情報に関するテーブルのそれぞれについて、Subjectクラスをaしたクラスを作成する。」と記載されています。また、View についても「グラフには複数の種類があるので、その種類ごとに、Viewクラスをaしたクラスを作成する。」とあります。
- これは基底クラス(Subject/View)を継承して派生クラス(販売実績Subject など、棒グラフView など)を作るという意味です。UML では汎化(generalization)を “白抜き三角形の矢印” で表現します。
- 図3の凡例でも「→ 継承(c)」と矢印を示しており、c には汎化を示す矢印が入ると分かります。
- 模範解答の「⇧」は、UML 汎化矢印(白三角)の簡易表記ですので、c は継承(汎化)を示す矢印「⇧」となります。
誤りやすいポイント
- 「Subject から View へ1対1」と誤読する
addObserver で配列登録しているため 1:1 ではありません。 - View―Subject を双方向関連と早合点する
本設計では View は Subject を知らず、Subject 側だけが View 配列を保持します。 - 汎化(継承)と依存を混同する
DAO ←→ 集計処理 は依存、Subject/View の派生は汎化です。
FAQ
Q: View が1つだけなら多重度は 1 では?
A: 時点によっては登録 View が0の場合もあるため “0..*” が最も汎用的です。
A: 時点によっては登録 View が0の場合もあるため “0..*” が最も汎用的です。
Q: c の矢印を「→」と書くのは誤り?
A: 凡例に合わせて白抜き三角の汎化矢印(⇧)を使う必要があります。
A: 凡例に合わせて白抜き三角の汎化矢印(⇧)を使う必要があります。
Q: Subject 側の多重度は指定しなくても良い?
A: 問題文では View 側のみ空欄指定だったため、Subject 側(1)を明示する必要はありません。
A: 問題文では View 側のみ空欄指定だったため、Subject 側(1)を明示する必要はありません。
関連キーワード: Observerパターン, 汎化, 多重度, 集約, MVC
設問3:
本文中の下線①について、関係する Subject オブジェクトのクラス名を図3中から選び全て答えよ。
模範解答
販売実績Subject, 販売明細Subject
解説
解答の論理構成
- 対象グラフが示すデータを確認
- 問題文より引用:「“時間帯ごと商品分類ごとの売上金額”のグラフ」
- 必要な情報は
① 時間帯(販売日時)
② 商品分類ごとの売上金額
- 時間帯(販売日時)を保持するテーブルを特定
- 図3の Subject 継承ツリーに「販売実績Subject」がある。
- 販売日時を管理するテーブルは“販売実績”であるため、該当する Subject は「販売実績Subject」。
- 商品分類ごとの売上金額を算出するために必要な明細データを特定
- 商品別・数量別の売上は明細レベルで保持される。図3には「販売明細Subject」が定義されている。
- よって、商品分類ごとの集計には「販売明細Subject」も関係する。
- 在庫Subject など他の Subject が関係しない理由
- 在庫Subject は在庫数の更新に関係し、売上金額・販売日時とは直接関係しない。
- 以上より、①で addObserver を呼び出す「関係する Subject オブジェクト」は
- 「販売実績Subject」
- 「販売明細Subject」
誤りやすいポイント
- 「商品分類」の文字を見て在庫管理を連想し、「在庫Subject」を含めてしまう。
- 集計は商品分類単位だが、商品分類のマスタは Subject 化されていない点を見落とす。
- 「販売実績Subject」だけで売上金額が取れると考え、明細が必要なことを忘れる。
FAQ
Q: 商品マスタや商品分類マスタが Subject にないのはなぜですか?
A: これらのマスタは頻繁に更新されず、リアルタイム監視の対象外と判断されたためです。販売データ更新に伴い通知する必要があるのは「販売実績」と「販売明細」です。
A: これらのマスタは頻繁に更新されず、リアルタイム監視の対象外と判断されたためです。販売データ更新に伴い通知する必要があるのは「販売実績」と「販売明細」です。
Q: もし在庫推移グラフを追加する場合はどの Subject が必要ですか?
A: 在庫数更新を検知する「在庫Subject」を addObserver する必要があります。
A: 在庫数更新を検知する「在庫Subject」を addObserver する必要があります。
Q: 明細データが大量でも過負荷にならないのですか?
A: 設計上、連続更新による過負荷回避策として View 側に“更新フラグ”を導入し、一定間隔でまとめて再描画する方式が採用されています。
A: 設計上、連続更新による過負荷回避策として View 側に“更新フラグ”を導入し、一定間隔でまとめて再描画する方式が採用されています。
関連キーワード: Observerパターン, 集計処理, クラス図, リアルタイム更新, データモデリング
設問4:
本文中のd、eに入れる適切な字句を答えよ。
模範解答
d:抽象
e:棒グラフView
解説
解答の論理構成
-
View クラスの 画面表示更新 の性質
- 【問題文】には「View クラスの画面表示更新メソッドはdメソッドなので…」とあります。
- また図3のクラス図では、View にイタリック(斜体)指定はありませんが、画面表示更新( ) は下位クラスごとに再定義されていることが示唆されています。
- さらに「グラフには複数の種類があるので、その種類ごとに、Viewクラスをaしたクラスを作成する。」とあるように、View は共通インタフェースのみを持ち、処理本体は派生クラス側で具体化します。
- したがって dメソッド に入るのは実装を持たない「抽象」であると論理的に導けます。
➡ d:抽象
-
どの派生クラスのメソッドか
- 同じ文には「例えば、“時間帯ごと商品分類ごとの売上金額”の場合はeクラスに実装されたメソッドを呼び出す。」とあります。
- 同じ段落冒頭の〔グラフの新規表示〕では「グラフの種類は棒グラフなので、棒グラフ View クラスのオブジェクトを作成する。」と明記されています。
- よって 画面表示更新 を具体的に実装しているのは 棒グラフView クラスです。
➡ e:棒グラフView
誤りやすいポイント
- 「抽象→具体」の流れを見落として View 自体に処理を書くと誤答になりやすいです。
- 図3に斜体表記が無いことから「抽象」と結び付けにくく、protected や virtual などキーワードを連想してしまうミスが起きやすいです。
- e は「グラフの種類=クラス名」であることを忘れ、View や Controller と書いてしまうケースも散見されます。
FAQ
Q: 「抽象メソッド」とは実際に何を意味しますか?
A: 本体を持たず、サブクラスで必ずオーバーライドされることを前提としたメソッドです。本問題でも View 自体は描画ロジックを持たず、派生クラスが実装します。
A: 本体を持たず、サブクラスで必ずオーバーライドされることを前提としたメソッドです。本問題でも View 自体は描画ロジックを持たず、派生クラスが実装します。
Q: なぜ 棒グラフView だと断定できるのですか?
A: 【問題文】に「グラフの種類は棒グラフなので、棒グラフ View クラスのオブジェクトを作成する。」と明記されており、サンプルケースとクラス名が一致しているためです。
A: 【問題文】に「グラフの種類は棒グラフなので、棒グラフ View クラスのオブジェクトを作成する。」と明記されており、サンプルケースとクラス名が一致しているためです。
Q: 他のグラフでも同じ流れになりますか?
A: はい。例えば円グラフを追加する場合は 円グラフView が生成され、画面表示更新 はそのクラスで実装されたメソッドが呼び出されます。
A: はい。例えば円グラフを追加する場合は 円グラフView が生成され、画面表示更新 はそのクラスで実装されたメソッドが呼び出されます。
関連キーワード: 抽象メソッド, 継承, オブザーバ, クラス図, ポリモorphism
設問5:
本文中下線②について、仕様変更の内容を30字以内で答えよ。
模範解答
引数に絞込条件クラスのオブジェクトを追加する。
解説
解答の論理構成
- 【問題文】には次の記載があります。
「View オブジェクトが画面の表示を更新する際に、絞込条件のオブジェクトが引き渡されるようにするために、Subject クラスの notifyObservers メソッドと、Viewクラスの notify メソッドのそれぞれについて、呼出しの②仕様を変更する。」
ここで“絞込条件のオブジェクト”とは、同段落冒頭で導入された「絞込条件クラス」のインスタンスです。 - 変更の目的は「絞込条件のオブジェクトを View 側へ渡す」ことです。渡す手段として最も自然なのは、両メソッドに“引数”として追加することです。
- したがって、“②仕様変更”の内容は「引数に絞込条件クラスのオブジェクトを追加する」となります。
誤りやすいポイント
- 「絞込条件をクラス変数に保持する」と誤解し、引数追加ではなく“共有属性化”と答えてしまう。
- notifyObservers だけ、あるいは notify だけに引数を足すと思い込み、両方を対象にしない。
- “絞込条件”という言葉を省き「条件を渡す」とだけ書き、具体性が足りず減点される。
FAQ
Q: なぜ Controller ではなく Subject/View 間で引数を追加するのですか?
A: 絞込条件は画面更新のたびに変化し得る操作情報であり、更新通知と同時に View へ受け渡すのが効率的だからです。Controller は更新契機を受け取るだけで、実際の再描画は View が担当します。
A: 絞込条件は画面更新のたびに変化し得る操作情報であり、更新通知と同時に View へ受け渡すのが効率的だからです。Controller は更新契機を受け取るだけで、実際の再描画は View が担当します。
Q: notifyObservers と notify の両方を変更する必要があるのはなぜですか?
A: Subject→View の呼出し階層が2段階あるためです。Subject が View を呼び出す部分(notifyObservers)と、View 自身の処理入口(notify)双方で新しい引数を受け取れる形に揃える必要があります。
A: Subject→View の呼出し階層が2段階あるためです。Subject が View を呼び出す部分(notifyObservers)と、View 自身の処理入口(notify)双方で新しい引数を受け取れる形に揃える必要があります。
Q: 絞込条件オブジェクトは常に渡されますか?
A: Controller が setFilter で設定したときのみインスタンスが渡され、それ以外は null もしくは空オブジェクトとして扱う設計が一般的です。
A: Controller が setFilter で設定したときのみインスタンスが渡され、それ以外は null もしくは空オブジェクトとして扱う設計が一般的です。
関連キーワード: オブザーバパターン, フィルタリング, 引数追加, オブジェクト指向設計
設問6:
本文中のfに入れる適切な字句を、30字以内で答えよ。
模範解答
f:複数のSubjectオブジェクトに登録される
解説
解答の論理構成
- 【問題文】では、「Controller クラスは、dbUpdated メソッドが呼び出されると、更新されたテーブルに対応する Subject オブジェクトの notifyObservers メソッドを呼び出す。」とあります。
- 各 Subject オブジェクトは「views 配列に格納されている全ての View オブジェクトの notify メソッドを呼び出す」ため、同じ View オブジェクトが複数の Subject に登録されていると、その数だけ notify が連続して発生します。
- その状況を説明する文が「一つの View オブジェクトはfで、1回の販売実績の登録で、表示の更新が複数回発生してしまう。」です。
- 問題となっている原因は「同一 View が Subject ごとに重複登録される」ことなので、f に入るべき語句は「複数のSubjectオブジェクトに登録される」となります。
誤りやすいポイント
- 「View が多重度 0..* で Subject に集約されている=View が Subject を複数持つ」と勘違いしやすいですが、実際は Subject が View を保持します。
- 「販売実績の登録 ➔ 販売実績Subject だけが通知」と早合点し、在庫や販売明細Subject も同時に動くケースを見落としがちです。
- 更新が複数回発生する理由を「DAO へのアクセス回数」や「画面描画ループ」に求めてしまい、Observer 内の重複通知だと気付かないことがあります。
FAQ
Q: なぜ View を複数の Subject に登録する必要があるのですか?
A: 1 つのグラフが複数テーブル(例:販売明細・商品マスタ)を集計対象にする場合、それぞれのテーブル更新を検知するために各 Subject へ登録します。
A: 1 つのグラフが複数テーブル(例:販売明細・商品マスタ)を集計対象にする場合、それぞれのテーブル更新を検知するために各 Subject へ登録します。
Q: どうすれば過負荷を抑えられますか?
A: 問題文のとおり「更新フラグ」を追加し、notify ではフラグ立てのみ、別スレッド等で一定間隔ごとに画面更新を行うことで過剰な再描画を回避できます。
A: 問題文のとおり「更新フラグ」を追加し、notify ではフラグ立てのみ、別スレッド等で一定間隔ごとに画面更新を行うことで過剰な再描画を回避できます。
Q: Controller クラスの setFilter はどのタイミングで呼ばれますか?
A: ユーザーがグラフ上でクリック操作を行い、View が絞込条件オブジェクトを生成した直後に Controller の setFilter が呼び出されます。
A: ユーザーがグラフ上でクリック操作を行い、View が絞込条件オブジェクトを生成した直後に Controller の setFilter が呼び出されます。
関連キーワード: Observerパターン, 集約関係, コンポジション, イベント通知, フラグ管理


