ページ 11

ファクトリーメソッドパターンの拡張について

Posted: 2011年1月04日(火) 20:56
by bbcs
デザインパターン?についての質問です
言語はC++です

ファクトリーメソッドパターンというものを、下のサイトで勉強したのですが、
http://www.geocities.jp/ky_webid/design ... n/002.html

このサイトのファクトリーメソッドパターンのサンプルを見ると、

メイン関数でファクトリークラスを生成

「メイン関数から」ファクトリークラスの関数を呼び出してクラスProduct A,Bを生成


と、なっているのですが、これを

メイン関数でファクトリークラスを生成

「メイン関数から」ファクトリークラスの関数を呼び出して クラスProduct A を生成

「生成したクラスProduct Aから」、メイン関数で生成したファクトリークラスの関数を呼び出して クラスProduct Bを生成

このように変更したいのですが、どうすればよいのか全く思いつきません
上記のようなファクトリーメソッドパターンの、考え方の御教授をおねがいします・・・

Re: ファクトリーメソッドパターンの拡張について

Posted: 2011年1月04日(火) 22:58
by sizuma
デザインパターンは全然知らないです。
Factoryクラスをシングルトンにして、コンストラクタでgetInstanceしておけば、参照自体はメインで生成したものと同じインスタンスですよね。

まぁ、僕だったらProductAで新しいインスタンスを生成します。もしくはProductAを生成するときに、Factoryクラスの参照を渡すとか。

Re: ファクトリーメソッドパターンの拡張について

Posted: 2011年1月04日(火) 23:59
by たいちう
どうしたら実装できるかについては、sizumaさんの書いてある方法で可能でしょう。
それよりも変更すべきかどうか、必要な仕様を整理して考えてみてはどうでしょうか。

ファクトリーメソッドパターンの「拡張」と書かれていますが、
もしProductの抽象性が失われるのでしたら、
ファクトリーメソッドが「台無し」になってしまうかもしれませんよ。

Re: ファクトリーメソッドパターンの拡張について

Posted: 2011年1月05日(水) 19:31
by bbcs
sizumaさん、たいちうさん 返信ありがとうございます
getInstanceやシングルトンなど聞いたことの無い言葉が出てきて
もっと勉強してから取り組まないといけないなと思ったので勉強して理解を深めてからまた質問したいと思います(もちろん、返信の内容を参考にしてからです)
ありがとうございました

Re: ファクトリーメソッドパターンの拡張について

Posted: 2011年1月06日(木) 06:12
by sizuma
分かりにくかったら申し訳ないです。稚拙ながらアドバイスさせていただきますね。

シングルトンはデザインパターンの中で一番簡単で使いやすいパターンです。
一つしかインスタンスを生成したくないっていう状況に適用するパターンで、参考にされてるサイトの9章にあります。
getInstanceっていうのは用語というより僕だったらインスタンスを取得するときにこういう名前をつけるっていうことで書いたもので、9章のページでもGetInstanceっていうstaticメソッドにしていますね。シングルトンを使ったことがなければピンとこなかったでしょう。すいません。

たいちうさんも書かれていますが、Factoryパターンの利点を損なわないように実装しなくてはだめです。
デザインパターンっていろんなパターンがあるけど、それを使ってプログラムの可読性、生産性などを上げるためのものですよね。

このパターンで大事なところは
・Factoryパターンをつかうことで、Factoryクラスにインスタンスの生成を一元管理させることができる。
ってことだと思います。また、工場で生成されるインスタンスは同じような機能を実装しているものがよいでしょう。
ProductAとProductBでは使える関数が違うってなると、Productの抽象性が失われてしまうことになります。
たいちうさんの書かれている抽象性が失われるっていうのはこういうことだと思います。
例えば、こんな感じですかね。
牛乳工場(MilkFactoryクラス)では牛乳(Milkクラス)を作っています。
生成された牛乳の機能として、なんとチーズ(Cheeseクラス)も生成できます!

・・・・・なんだこの例は。放置すれば牛乳ってチーズになりそうだから、ありっちゃありか(ない)。
一般的に考えて、牛乳の機能にチーズを生成するってのはないですよね。
さらに”セブンイレブンの牛乳”と”ドンキホーテの牛乳”で違う機能(関数)があると分かりづらくないですか?
ここらへんはクラスの継承の考え方と同じと思ってくれればいいです。

また、Factoryクラスでせっかく明示的にCreateInstanceをして生成いるのに、生成されるインスタンスの関数からもインスタンスを生成できると分かりにくくなってしまいませんか?
メイン関数でProductAがFactoryクラスを使ってProductBを取得するよりも、メイン関数からFactoryクラスで直接取得するほうが分かりやすと僕は思います。



いろいろ書いてますけど、僕別にデザインパターンに精通してるわけじゃないんで、参考程度にお願いします。
むしろFactoryとか使ったことないぐらいなんで。
(Factoryがあんまり使わないという意味ではなく、それくらいプログラミングしてないって意味です)