質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

Q&A

解決済

1回答

1644閲覧

ファクトリパターンに関する一般的な質問

xxxx

総合スコア13

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

0グッド

2クリップ

投稿2016/01/31 15:09

こんにちは、最近オブジェクト指向設計の勉強を始めたばかりの者です。

今のところプログラム言語についてはPHPしか知らないので、回答例などをいただける場合はPHPのコードを示していただけるとありがたいです。(でも、Javaのコードもなんとなく読めます。)

デザインパターンについての質問です。次の疑似コードはAbstractFactoryパターンの概念の説明のためにとあるサイトに載っていたものです。

interface C{}

class A implement C {}
class Z implement C {}

abstract class CFactory{
abstract C newInstance();
}

class AFactory extends CFactory{
C newInstance(){
return new A():
}
}

class ZFactory extends CFactory{
C newInstance(){
return new Z():
}
}

class B {
method(){
C = CFactory.newInstance();
}
}

私が理解しているのは、「クラスAまたはZを使うクラスBが、使うクラスのインスタンス化をクラスCFactoryに丸投げすることで、クラスAまたはZへの依存度を下げている」というところまでです。

そこで、この疑似コードに関する質問ですが、

1.クラスBがクラスAまたはZのインスタンスを得るためにコールしているクラスCFactoryのnewInstance()メソッドですが、これはCFactoryをnewしていない(できない)以上、スタティックメソッドと考えていいのでしょうか?しかもこれは抽象メソッドですが直接コールすることができるのでしょうか?

2.この例では結局インスタンス化されるのはクラスAですか?それともクラスZですか?また、その選択のロジックはどこに書かれている(または、書かれるべき)でしょうか?

ファクトリパターンの勉強をしようと思って、ネットであれこれ調べてみても概念を説明する疑似コードや図は見つかるのですが、具体的な実装については未だに理解できません。

ご教授のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

単純に、class Bの内容が間違っています。
抽象メソッドは直接呼べません。
正しくは、以下のようなコードになります。

Java

1void method(CFactory factory) { 2 C instance = factory.newInstance(); 3}

具体的なファクトリのインスタンスは、外部から与えられます。
そのファクトリを使って、具体的なインスタンスを生成します。

投稿2016/01/31 16:05

編集2016/01/31 16:06
Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xxxx

2016/02/01 05:26

ご回答ありがとうございます。 なるほど、やはりCFactoryを継承するクラスはどこかでnewする必要があるわけですね。 ということは、Stripeさんの回答例ではクラスBのmethod(CFactory factory)を使う者が、CFactoryの実装としてAFactoryまたはZFactoryを選んで、newしたものを引数としてmethodに渡しているという理解で間違いないでしょうか? そうすると、AFactoryクラスまたはZFactoryクラスを選んでnewしているのは誰か?という問題が依然残ったままですが、これをクラスB側でやってしまうと、結局クラスAまたはZへの依存度を下げたことにはなりませんし、CFactory側でやるにしても、わざわざ抽象ファクトリクラスを一枚かませて多態性を持たせている意味がよく分かりません。 もしよろしければ、その辺に関するご解説をいただけるとありがたいです。
Stripe

2016/02/01 10:00

ファクトリは、外部のコンポーネントで生成されます。(当然、class Bではありません) ファクトリの利用者からは、そのファクトリの実体が何なのか分かりません。 ファクトリの利用者側では、ファクトリを生成しません。 また、ファクトリ自体も外部で定義されます。
xxxx

2016/02/01 14:11

度々のご回答ありがとうございます。 CFactoryを継承するAFactoryまたはZFactoryのインスタンスを返すコンポーネントが外部にあることで、interface Cの実装がクラスBから完全に隠蔽されたわけですが、この外部のコンポーネントというのはCFactoryクラス(を継承するファクトリクラス)のインスタンスを返すCFactoryFactoryのようなクラスがあるという理解でよろしいでしょうか? つまり、こんな感じ? class CFactoryFactory { createCFactory(){ //どちらのインスタンスを返すかは、AまたはZを提供する側の事情による。 return new AFactory(); //return new ZFactory(); } } でもそれならば、最初からCFactoryを抽象クラスにせずに class CFactory { createC(){ return new A(); //return new Z(); } } としてもいいような気がするのですが・・・??? 再三の質問で恐縮ですが、ここがまさに私がAbstractFactoryパターンをいま一つ理解できないでいるポイントなのです。CFactoryを抽象クラスにする理由とはいったい何なのでしょうか? (私の考えた可能性としては、クラスAとクラスZのインスタンスの生成がここに書かれた例のようにシンプルなものではなく、全く異なる複雑な生成ロジックに基づいて生成されるというような場合で、それであればCFactoryFactoryを設けてでも生成プロセスを受け持つ個別のファクトリクラスを作ったほうが良いという結論になるのですが、この考え方で正解でしょうか?)
Stripe

2016/02/01 14:50

ファクトリが生成するインスタンスは通常複数です。 今回は、interface Cしか定義していませんが、本来ならD、E、F...と複数定義されることが想定されています。 ファクトリを替えることで、あるインスタンスのセットを丸ごと差し替えられるようになります。
xxxx

2016/02/01 15:41

おお、なるほど!一つの工場につき複数の生産ラインというイメージでしょうか。 それであれば、工場を丸ごと取り換えられるメリットも理解できます。 本当にありがとうございました。これで次に進めます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問