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

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

新規登録して質問してみよう
ただいま回答率
85.50%
デザインパターン

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

Q&A

2回答

3556閲覧

【デザインパターン】Factory Methodパターンでは具象クラスとの依存度を下げることはできない。

takenyaan

総合スコア119

デザインパターン

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

1グッド

2クリップ

投稿2017/01/31 09:38

編集2022/01/12 10:55

デザインパターンの一つであるFactory Methodを調べていて気になった点を質問させてください。

Factoryパターンのメリット
Factory Methodに限らず、一般的にオブジェクトの生成のためのFactoryを設けることのメリットは以下の通りと認識しています。

・ インスタンスの生成処理を隠蔽化できる
・ そのためクライアントが利用したいオブジェクトの具象から分離される。(具象オブジェクトをnewしない)

java

1interface Producer { 2 // いくつかのメソッド 3} 4class AProducer implements Producer { 5 // Producerの実装 6} 7 8// ファクトリ 9class ProducerFactory() { 10 public Producer createProducer() { 11 return new AProducer(); 12 } 13} 14 15// クライアント 16class Main() { 17 public static void main(String[] args) { 18 Producer p = ProducerFactory.createProducer() 19 } 20}

Factory Methodパターン
Factory Methodパターンの場合、生成したいオブジェクトの種類に応じてファクトリを用意することになるので、
「クライアントが利用したいオブジェクトの具象から分離される。」メリットを完全に失っている気がします。

※実際に利用したいオブジェクトには依存してませんが、そのオブジェクトを生成するためのファクトリに依存している(newしている)ため。利用するオブジェクトが変われば当然ファクトリも変えざるを得ず、クライアントのコードに修正が発生します。

java

1interface Producer { 2 // いくつかのメソッド 3} 4class AProducer implements Producer { 5 // Producerの実装 6} 7 8class BProducer implements Producer { 9 // Producerの実装 10} 11 12// ファクトリ 13abstract class ProducerFactory { 14 public abstract Producer createProducer(); 15} 16class AProducerFactory extends ProducerFactory { 17 public Producer createProducer() { 18 return new AProducer(); 19 } 20} 21class BProducerFactory extends ProducerFactory { 22 public Producer createProducer() { 23 return new BProducer(); 24 } 25} 26 27// クライアント 28class Main() { 29 public static void main(String[] args) { 30 Producer ap = new AProducerFactory().createProducer() 31 Producer ap = new BProducerFactory().createProducer() 32 } 33}

このようにFactory Methodパターンはクライアントと具象クラスが密結合になってしまうデメリットがあると考えます。
オブジェクトの生成処理においてテンプレートメソッドを利用する場合は意味があるとは思いますが、
それ以外の場合に敢えてFactory Methodを用意するメリットはありますでしょうか?
むしろオブジェクトの生成処理は1ファクトリクラスに集約したほうが、疎結合なつくりにできるのではないかと考えています。

ご意見頂けますと幸いです。

参考
http://think-on-object.blogspot.jp/2011/11/factoryfactory-methodabstract-factory.html
http://d.hatena.ne.jp/asakichy/20090414/1239718537
http://d.hatena.ne.jp/asakichy/20090331/1238472501
http://www.nulab.co.jp/designPatterns/designPatterns2/designPatterns2-2.html

sin_250👍を押しています

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

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

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

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

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

guest

回答2

0

#結論
Factory Methodパターンはインターフェースに依存した作りにすることで、
よりメリットを享受できるようになります。

#内容
サンプルのソースコードを確認いたしましたところ、
実クラスごとにFactoryクラスを作ってしまっており、メリットが「依存性の委譲」のみになってしまっているように見えました。

Java

1interface Producer { 2 // いくつかのメソッド 3} 4class AProducer implements Producer { 5 // Producerの実装 6} 7 8class BProducer implements Producer { 9 // Producerの実装 10} 11 12// ファクトリ 13class ProducerFactory() { 14 public Producer createProducer( String type ) { 15 16 if ( "A".equals( type ) ) { 17 // Aが指定されたのでAProducerを生成 18 return new AProducer(); 19 } 20 21 if ( "B".equals( type ) ) { 22 // Bが指定されたのでBProducerを生成 23 return new BProducer(); 24 } 25 // 何らかのエラー処理 26 } 27} 28 29// クライアント 30class Main() { 31 public static void main(String[] args) { 32 ProducerFactory producerFactory = new ProducerFactory(); 33 34 // 中身はAProducer 35 Producer ap = producerFactory.createProducer("A"); 36 37 // 中身はBProducer 38 Producer bp = producerFactory.createProducer("B"); 39 } 40} 41

このようにFactoryクラスをインターフェースに依存するように作成し、
引数で指定できるようにゆとりを持たせると、
新しくCproducerが必要になった際に、ProducerFactoryクラスの改修のみですみます。

また、Mainから見た際に、引数のみ知っていれば、実クラスのことを全く知らなくても、
オブジェクトを生成することができます。

#追記
また、JavaであればSpringBootなどのフレームワークを使用することで、コンストラクタインジェクションや、DIでFactoryクラスの生成処理を他に委譲しさらに抽象度を高めることもできます。

投稿2017/01/31 11:05

satouryou

総合スコア70

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

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

maisumakun

2017/01/31 11:10

domのdocument.createElement()みたいに、「同じファクトリーが共通のインターフェースだけど、違う子クラスを返す」ような実装も可能ですからね。
guest

0

クライアントと具象クラスが密結合になってしまう

本当になっていますか?Mainの側から見れば、どのファクトリーを使うにしても、「ProducerFactoryのインスタンスに対してcreateProducer()をすればProducerが生成する」という点では共通していますので、生成物をProducerとして扱えればよい場面では、ファクトリーを適宜差し替えることができます。

Producerの実際のクラスを気にするのであれば、それはもうポリモーフィズムを適用できないので、まったくの別問題です。

投稿2017/01/31 10:46

編集2017/01/31 10:47
maisumakun

総合スコア145121

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問