オブジェクト指向のこころー演習問題(第3部)


以下の問題及び回答は書籍を参考に記載しています。また一部引用があります。

第5章:デザインパターンの紹介

基礎

Q1. デザインパターンというアイデアを考え出した人は誰でしょうか?
A1. Christopher Alexanderという建築家

Q2. Alexanderは同様の問題を解決する構造を見ることで、何を見つけ出したのでしょうか?
A2.パターン。類似点。

Q3. パターンを定義してください。
A3. 問題を解決する構造に見られる類似点。パターンを描写するには、以下4つを備えている必要がある。
・パターンの名前
・パターンの目的(解決する問題)
・その達成方法
・達成する上で考慮する必要がある制約とフォース

Q4. デザインパターンの解説で鍵となる要素は何でしょうか?
A4.以下、ソフトウェアの場合
・名前:各パターンを識別するための固有名
・目的:このパターンの目的
・問題:パターンが解決しようとしている問題
・解決策:問題が生じているコンテキスト内における、このパターンを用いた解決方法
・構成要素と協調要素:このパターンに関係する実体
・因果関係:このパターンを使用することによる因果関係を記述。パターン中に現れるフォースを詳細に調べたもの。
・実装:パターンの実装方法
・一般的構造:パターンの一般的な構造を示した標準的なクラス図

Q5. デザインパターンを学習する3つの理由とは何でしょうか?
A5.
・解決策の再利用:すでに確立されている設計を再利用することで、問題解決に向けて細々した詳細をさけることが出来る。また、何度も繰り返されている問題の解決策を再発明する必要がなくなる。
・共通用語の確立:デザインパターンによって、プロジェクトの分析工程と設計工程における共通の基準点が設定できる。これは、コミュニケーションを円滑にし、チームワークをよくする。なぜなら、問題に対する共通のボキャブラリと共通の認識を持つ
ことが出来るから。
・コードの修正可能性と保守性の向上

Q6. GoFは優れたオブジェクと指向設計を生み出す戦略を示唆しています。それらは何でしょうか?
A6.
・インタフェースを用いて設計をする。
・クラス継承よりもオブジェクとの集約を多用する
・流動的要素を見つけ出し、それをカプセル化する。

応用

Q1. 「慣れすぎてしまうことで、明らかなものを見失ってしまうことがあります。」パターンを使うことで、どのようにしてこういったことを避けることが出来るのでしょうか?
A1. 経験によって培われた知識を、未経験者でも活用できるようになる。(優れた設計に必要なことと貧弱な設計を避けるために必要なことが明確になる)

Q2. GoFは23のパターンをカタログ化しました。これらのパターンはどうやって生まれたのでしょうか?
A2. ソフトウェアコミュニティ内にすでに存在していた、特定の問題を解決する品質の高い設計から学び取った教訓をパターンとして洗い出した。

Q3. パターンにおける「因果関係」と「フォース」の関係とはどのようなものでしょうか?
A3. パターンによって周囲にどのような影響が発生するか、存在しているフォースによってパターンにどのような影響が発生するかということを因果関係と呼ぶ。フォースは特定の状況下において解決策を限定する制約のこと。

Q4.「流動的要素を見つけ出し、カプセル化する」とは、どういったことを意味していると思いますか?
A4. 他のオブジェクトから流動的要素が隠蔽され、他のオブジェクとからは、何ら変更がないように見えること。

Q5. 深い継承改装を避けたほうがよいという理由は何でしょうか?
A5. 依存関係がわからなくなる?(多重継承などの発生。)

第6章:Facadeパターン

基礎

Q1. Facadeを定義してください。
A1. クライアントが既存システムのインタフェースを使用しなくてもよいよう、新たなインタフェースを生成する。

Q2. Facadeパターンの目的は何でしょうか?
A2. 既存のシステムの使用方法を簡素化したい。独自のインタフェースを定義する必要がある。GoFによると、サブシステム内に存在していうる複数のインタフェース群に対する、統一したインタフェースを提供する。Facadeは高レベルのインタフェースを定義することにより、サブシステムを用意に使えるようにするものである。

Q3. Facadeパターンの因果関係とは何でしょうか?例を上げてください。
A3. 要求されたサブシステムの使用方法を簡略化して提供する。しかし、このパターンはすべての機能を提供するものではないため、ある種の機能はクライアントから利用できない可能性がある。
例えば、CAD/CAMシステムにおいて、modelから触る機能だけをFacadeで集約して、各サブシステムに渡す。

Q4. Facadeパターンにおいて、クライアントはどのようにしてサブシステムと協調するのでしょうか?
A4. Facadeが提供するmethodを通じて、サブシステムにアクセスする。

Q5. Facadeパターンを使った場合、通常はシステム全体にアクセス出来るようになるのでしょうか?
A5. ならない。

応用

Q1. GoFはFacadeパターンの目的を「サブシステム内に存在している複数のインタフェース群に対する、統一したインタフェースを定義することにより、サブシステムを用意に使えるようにするものである」と述べています。これ意味を説明してください。また、この例を挙げてください。
A1. クライアントからサブシステムにアクセスする際に、それぞれのサブシステム毎にアクセス方法をクライアントに定義するのではなく、別途統一したインタフェースを定義することにより、クライントがこのインタフェースからサブシステムにアクセスするようにすること。
例:???

Q2. 以下はソフトウェアとは関係のないfacade例です。以下以外に、実生活におけるFacadeの例をもう一つ上げてください。
例:アメリカ酷ないにあるガソリンスタンドの供給装置は、支払い方法、給油する燃料の種類、広告表示等多くのオプションがあり、非常に複雑なものとなっています。このインタフェースを統一する方法の一つは、スタンドの係員にまかせてしまうことです。州によっては、係員の操作が義務付けられているところもあります
A2. 日本の地下鉄の路線は複雑に張り巡らされており、目的駅に向かう乗り換えを把握するためには、乗り換えと時刻表を把握している必要があるが、路線乗り換えアプリにより、ユーザはスタートとゴールの駅を入力するだけで、乗り換えを把握できる。(しかし、乗り換え以外の情報はそこからは把握できない)

第7章:Adapterパターン

基礎

Q1. Adapterを定義してください。
A1. クラスまたはクラス群のインタフェースを望みどおりのインタフェースに変換すること

Q2. Adapterパターンの目的は何でしょうか?
A2. 修正することのできない既存オブジェクとを、特定のいんたフェースに適合させる。GoFによると、「あるクラスのインタフェースを、クライアントが望むインタフェースに変換する。Adapterによってクラス群は互換性のあるインタフェースを持つことになり、協調して動作できるようになる」

Q3. Adapterパターンの因果関係とは何でしょうか?例を上げてください。
A3. Adapterパターンにより、既存オブジェクとをそのインタフェースに制限されることなく、新たなクラス構造に取り込むことが可能になる。
例:Point, Line, Square, Circleをクライアントから操作することを考える。クライアントは、実際には「表示可能な形状」という機能がほしいので、ポリモーフィズムを利用し、これらの抽象クラスShapeをつくり、ここから統一的に操作を行う。このとき例えば既存に実装として、メソッド名やパラメータがShapeと異なり、継承関係にもない、XXCircleがすでに実装されているとする。このとき、CircleをXXCircleのラッパとして実装するのが、Adapterパターンである。

Q4. ShapeとPoint, Line, Squareの間の関係を定義するために使用されているオブジェクと指向の概念とは何でしょうか。
A4. ポリモーフィズム。

Q5. Adapterパターンの最も一般的な使用方法とは何でしょうか?
A5. ある派生クラスから、既存のクラスを操作すること。

Q6. Adapterパターンを採用することによって、どういったことを意識しなくても良いようになるのでしょうか?
A6. クライアントオブジェクとが、実際に存在している型を意識しなくても済むようになる。

Q7. Adapterパターンは2種類に分類できます。それらを答えてください。
A7.
・Object Adapterパターン:あるオブジェクとが他のオブジェクとを保持するパターン。保持する側が、適合を行うオブジェクと。保持される側が適合される既存オブジェクト
・Clas Adapterパターン:他重軽傷を使用して実装するAdapterパターン。

応用

Q1. GoFはAdapterパターンの目的を「あるクラスのインタフェースを、クライアントが望むインタフェースに変換するもの」であると述べています。この意味を説明してください。例を上げてください。
A1. クライアントが実際にメッセージを受けるクラスとインタフェースに変換するクラスを既存のオブジェクトをラップする形で実装すること。
例:???

Q2. 「CircleオブジェクトはXXCircleオブジェクトのラッパです」という表現はどいういう意味をもっているのでしょうか?
A2. CircleオブジェクトがXXCircleを包み込んで、使用しやすくしたオブジェクとであるということ。

Q3. FacadeパターンとAdapterパターンは一見するとよく似ています。これら2つの本質的な違いを述べてください。
A3. Facadeパターンはインタフェースを簡素化し、Adapterパターンは既存のインタフェースを他のインタフェースに変換する。

Q4. 以下はソフトウェアとは関係の内Adapterの例です。実生活におけるAdapterの例をもう一つ上げてください。
例:国連でさまざまな国の外交官たちが集まり、自国の立場を自国の言語で討論していると考えてください。このとき、通訳はある言語から他の言語への交換を行うことで架空の外交官を動的に作り出し、受けてが聞きたい、そして聞く必要のあることを伝えています。
A4. 世界各国では、電気プラグの規格が異なっている。そのため、海外旅行のときなどは、これを変換するadapterを取り付けて、利用する。

第8章:視野を広げる

基礎

Q1. カプセル化について正しい認識とはどういったものでしょうか?
A1. あらゆるものの隠蔽。データの隠蔽が一般だが、その他にも実装、派生クラス、設計の詳細、実体化の規則を隠蔽できる。

Q2. 問題領域を見る際の3つの観点とは何でしょうか?
A2. 概念、仕様、実装

応用

Q1. オブジェクトの理解として「メソッドを伴ったデータ」と「責務を伴ったものごと」という2つの考え方があります。2つ目の考え方が1つ目のものよりも優れているのは、どういった点
においてでしょうか。またこれによって、どういった見識が追加されるのでしょうか?
A1. 2つ目の考え方によって立つことで、オブジェクトが何を実行するのかに着目できるようになる。これによって、詳細を全て考慮することなく、予備的な設計を行ったのち、実際の設計を行うことが可能となる。

Q2. オブジェクトは他のオブジェクトを保持することができるでしょうか?これはオブジェクトがデータメンバを保持することと違っているのでしょうか。
A2. 可能。オブジェクト指向の観点から見ると、特に大きな違いはない。

Q3. 「流動的要素を見つけ出し、それをカプセル化する」という言葉には、どういった意味があるのでしょうか?例を上げて説明してください。
A3. 使用側のクラスには、派生クラス群の上位階層に当たる、抽象クラスやインタフェースへの参照を保持させておく事で、派生クラス群を使用側のクラスから隠蔽する。
例えば、動物の移動を考えたときに、動物の移動手段は種類ごとに異なっているので、AnimalMovementクラスが、実際の移動手段であるAnimalFlyやAnimalWalkの抽象クラスとなり、AnimalクラスがAnimalMovementクラスを保持する。これにより、Animalクラスからは、AnimalMovementクラスを呼び出す事で、派生クラスを気にする必要がなくなる。

Q4. 共通性/可変性分析と問題領域を見る際の3つの観点の関係を説明してください。
A4.
・共通性分析:時が経っても変化しにくい構造を見つけるもの。抽象クラスによって表現する概念上の観点・仕様上の観点と関連がある。具体的には、共通性によって概念上の観点が定義され、仕様上の観点によって、ある概念に存在するケース全てを取り扱うためのインタフェースが洗い出される。
・可変性分析:変化しやすい構造を洗い出すもの。具象クラスによって表現する。仕様上の観点と実装上の観点に関連がある。具体的には、ある仕様が与えられた場合、その特定ケース(可変せい)における実装方法を決定する。

Q5. 抽象クラスは「中央集権の概念」と対応付けられます。これはどういった意味を持っているのでしょうか?
A5. 派生したクラス全てをまとめた核となる概念を表現する。共通性分析によって、定義される。

Q6. 「可変性分析によって、ファミリ構成員がどのように違っているのかが明らかになります。可変性は特定の共通性においてのみ意味を持ちます」これはどういった意味を持っているのでしょうか?、共通概念を表現するためには、どういった種類のオブジェクトが使用されるでしょうか?流動的要素を表現するためには、どういった種類のオブジェクトが使用されるでしょうか?
A6.
・意味:構成員が使用される際の共通性があるので、それぞれどのように違っているかがわかるということ。
・共通概念の表現:抽象クラスによって表現される
・流動要素の表現:与えられた仕様を満たす、派生クラス。

第9章:Strategyパターン

基礎

Q1. 新たな要求を取り扱う方法として、どのような方法があるでしょうか?
A1.どこに変更可能性があるかを予測する

Q2. GoFが提案した、変更に取り組む際の基本原則を3つあげてください。
A2.
・実装を用いてプログラミングするのではなく、インタフェースを用いてプログラミングしてください
・クラス継承よりもオブジェクトの集約を多用してください
・あなたの設計において、何を流動的要素とすべきかを考察してください。このアプローチは、再設計の原因に着目するというものとは正反対となっています。設計変更を強いる可能性のあるものが何かを考えるのではなく、再設計せず何を変更可能とするのかを考えるのです。ここで着目しているのは、流動的概念のカプセル化であり、多くのデザインパターンのテーマともなっているものです。

Q3. Strategyパターンの目的とは何でしょうか?
A3. 様々な業務上の規則(ビジネスルール)やアルゴリズムを、それが発生するコンテキストに応じて使い分けられるようにすること。

Q4. Strategyパターンの因果関係とは何でしょうか?
A4.
・アルゴリズムのファミリを定義する
・switchおよび条件分岐を無くすことができる
・全てのアルゴリズムは、同じ方法で起動しなければならない。

応用

Q1. GoFは「設計において、何を流動的要素とすべきかを考察する」とことを示唆しています。このことと再設計の原因に着目することは、どのように違っているでしょうか?
A1.
再設計の原因は、実装レベル・仕様レベル・抽象レベルのどのレベルにも存在するが、流動的要素に着目することで、実装レベル・仕様レベルへの考察に絞り込むことができる。

Q2. コピー&ペーストにおける問題とは何でしょうか?
A2.
後々保守する人が、コピペしたコードを全て見直す必要が出てくる。。

Q3. 「switchの泥沼」とは何でしょうか?
A3.
ある変数が複数のswitch内で用いられるようになった場合、新たな条件が発生すると、その条件に関係しそうな全ての部分を修正する必要が出てくる。

Q4. 流動的要素を取り扱う際、デザインパターンのアプローチを採用する利点は何でしょうか?
A4.
メンテナンスコストを下げ、コードをより柔軟にする。

Q5. 流動的要素を取り扱う際に、クラス継承アプローチよりもオブジェクトの集約のアプローチの方が優れているのは何故でしょうか?
A5.
・規模の大きい複雑なプログラムを単純化できる
・各流動的要素を独立したクラス階層内で管理できる。
・内部操作をシステム内の他の構成要素から自由に使用(テスト)できるようになっているので、拡張性を実現できる

第10章:Bridgeパターン

基礎

Q1. 切り出すという言葉と抽象的側面という言葉を定義してください
A1.
切り出す:物事が互いに独立して振る舞えるようにする。または、少なくとも、それらの関係を明確に述べる。
抽象的側面:様々な物事における概念的な特徴

Q2. Bridgeパターンのコンテキストにおける実装という言葉を定義してください。
A2. 抽象クラスとその派生物(具象クラス)が自らを実装するために必要とするもの。

Q3. シーケンス図の基本要素とは何でしょうか?
A3.
・オブジェクト
・オブジェクトのライフライン
・オブジェクトが互いに送信し合うメッセージ

Q4. パターンの使用方法に関するAlexanderの観点とは何でしょうか?彼は、まず最初に解決策から考察することを提唱しているのでしょうか?それとも解決すべき問題から考察することを提唱しているのでしょうか?
A4.
Alexanderの考え方は、「各パターンとは、我々の環境でなんども繰り返される問題を描写し、その後、問題を解決する上での核心を描写することで。。。」というもの。つまり、パターンは問題を描写するとともに、解決の核心でもある。この考察自体は、問題から描写する。

Q5. 共通性分析では何を洗い出そうとするのでしょうか?可変性分析では何を洗い出そうとするのでしょうか?
A5.
共通性分析:時が経っても変化しにくい構造を見つける。使用する必要のある抽象クラスを定義できる。
可変性分析:変化しやすい構造を見つける。共通性内で新井だされた流動的要素が派生クラスになる。

Q6. Bridgeパターンが解決する問題とは、基本的にどういったものでしょうか?
A6.
クラス数の爆発を招くことなく、抽象クラスの派生物から複数の実装を使用する必要がある。

Q7. 「一つの場所には一つの規則」という戦略を定義してください。
A7. 何かを行う規則がある場合、一度だけ実装するようにこころがけること。重複を避け、将来の修正部分の漏れを少なくすることができる。

Q8. Bridgeパターンの因果関係とは何でしょうか?
A8.
オブジェクトが使用している実装を、そのオブジェクトから切り離すことによって、拡張性を高める。クライアントオブジェクトは、実装に関するあれこれを気にする必要がなくなる。

応用

Q1. GoFはBridgeパターンの目的を「実装から抽象的側面を切り出して、それらを独立して変更できるようにする」ことであると述べています。この意味を解説してください。例をあげてください。
A1. 意味:抽象的側面を表す部分と、実装を表す部分に分けるということ。具体的には、実装をオブジェクトの外にあるものと捉えると、呼び出し側のプログラムから実装における流動的要素を隠蔽するということ。
例:図形を描画することを考えた時、図形を表すクラス(抽象的側面)と描画を表すクラス(実装)を分け、それぞれは抽象クラスとしてき、図形の抽象クラス内に描画の抽象クラスを集約すること。これによって、インターフェースが確立し、図形に関係なく描画できるとともに、描画の依存性に関係なく図形を選択できる。よって、抽象的側面と実装を独立に扱うことができ、抽象的側面からは、描画の流動的要素を隠蔽することができる。

Q2. 結合度が高くなると、なぜクラス数の爆発が生じるのでしょうか?
A2.
抽象的側面と実装が緊密に結合しているため、各抽象的側面の型が、自ら使用する描画のどの型に属しているかを知らなければならないため。

第11章:Abstract Factoryパターン

基礎

Q1. switchは、処理の選択を行う際に使用できる機能ですが、この章で考察したデバイスドライバの例では問題が引き起こされます。どういった問題が引き起こされるのでしょうか?またswitchによってどういったニーズが示されているのでしょうか。
A1.
問題:使用対象のデバイスドライバを決定する規則と、実際にデバイスドライバをしようするコードが一体化しており、結合度が高く、凝集度の低いコードになってしまっている。
ニーズ:ポリモーフィズムの導入や責務の見直しを検討のニーズのサインになっている。

Q2. このパターンは、どうして「Abstract Factory」と呼ばれているのでしょうか。
A2. 構築しようとしているもの自体が抽象化によって定義されているため。

Q3. Abstract Factoryにおける3つの概念的手順とは何でしょうか。
A3.
・どういった状況が存在するのか
・この情報をどのように管理するのか
・生成用のロジックをどこに記述するのか

Q4. このパターンでは、2種類のファクトリが存在しています。AbstractFactoryとは何をするものなのでしょうか。ConcreteFactoryMとは何をするものなのでしょうか。
A4.
AbstractFactory:オブジェクトのファミリを構成するメンバの生成要素インタフェースを定義する。
ConcreteFactoryM:各ファミリ専用のオブジェクトを生成する。

Q5. Abstract Factoryパターンの因果関係とは何でしょうか。
A5. どのオブジェクトを使用するのかという規則と、それらのオブジェクトの使用方法に関するロジックを分離することができる。

応用

Q1. GoFはAbstract Factoryパターンの目的として「関連、または依存し合うオブジェクトのファミリを、その具象クラスを指定することなしに生成するインタフェースを提供する」と述べています。この意味を答えてください。例をあげてください。
A1.
意味:抽象的側面と実装が、クライアントから見て、関連依存し合っている場合に、まず抽象的側面を切り出すことで、実装の違いを隠蔽する。さらに、実装(オブジェクトの生成)に関しても、そのファミリの抽象クラスを用意することで、クライアントはそれぞれに対して、具象クラスを指定することなしに生成を行う。
例:プリンタ・ディスプレイがそれぞれ解像度に高低がある場合に、プリンタとディスプレイを分離して、抽象クラスを用意する。さらに、各ドライバ(高解像度・亭解像度)の生成に関しても、抽象クラスを用意する。どちらのオブジェクトを生成するかは、クライアントから情報提供を行う。