【GoF】デザインパターン5

このエントリーをはてなブックマークに追加
932デフォルトの名無しさん:2005/10/14(金) 01:27:55
デフォルト・コンストラクタがないね(・∀・)
933デフォルトの名無しさん:2005/10/14(金) 03:03:30
ちなみに


<Hoge.cpp>
Hoge& Hoge:GetInstance(){
  static Hoge m_pInstance;
  return m_pInstance;
}
の方がスマートらしい
934デフォルトの名無しさん:2005/10/14(金) 03:34:16
そうかそうか、よーくわかったぞ。
935デフォルトの名無しさん:2005/10/14(金) 10:17:31
>>933
これって、クラスで唯一のインスタンスになってくれるの?

ってなってくれそうだね。
確かにスマートだ。
936デフォルトの名無しさん:2005/10/14(金) 11:35:47
>>927
ってデストラクタ内のdeleteでデストラクタが呼ばれて愉快なことにならないか?

937デフォルトの名無しさん:2005/10/14(金) 12:19:48
思いっきり楽しいことにぬるぽ。
938927:2005/10/15(土) 00:22:15
皆様ありがとうございます。解決しました。

>>927さんのいうとおり、確かに愉快なことになってます。
いろいろとWebで調べたら実際にこのようにプログラミングしていました。

実際はどのようにインスタンスを解放したらいいのでしょうか?
939デフォルトの名無しさん:2005/10/15(土) 05:06:55
>>938
PCをリセットしたまえ。
940デフォルトの名無しさん:2005/10/15(土) 09:44:57
これだけ言わせてくれ

 自 分 に さ ん 付 け す る な
941デフォルトの名無しさん:2005/10/15(土) 12:42:00
水木しげるみたいだ。
942927:2005/10/15(土) 18:58:06
すみません、アンカー間違えました。
よく考えたら、確かにdeleteでさらに同じデストラクタを呼びますが、
if文の判定で回避可能ではないでしょうか。

実際に実行してみると、約50%ぐらいの確率でデバッガ(VisualStudio)がメモリリークを検出します。
再現性に乏しくて大変困るのですが、何が原因かわかりますか?
943デフォルトの名無しさん:2005/10/15(土) 19:46:44
なんていうか、デザパタ以前にC++初歩の問題だな。
944デフォルトの名無しさん:2005/10/15(土) 21:25:58
>>942
if文うんぬんより、デストラクタ→デストラクタ→デストラクタ→・・・
の無限再帰ループでスタックオーバーフローしそうなんだけどどうなんだろ。

まあ、もう既にデザパタの話しでなくなってるので他スレにでもいってら。
945デフォルトの名無しさん:2005/10/15(土) 22:27:33
デザインパターンで画用紙メモリってどんなん?
946927:2005/10/15(土) 23:33:10
お騒がせしました。

結局auto_ptrを使用して回避することにしました。
947デフォルトの名無しさん:2005/10/16(日) 00:09:30
auto_ptrを使うことは構わないが、
結局問題の原因がわかってなければまた同じ問題を起こすわけで。
948デフォルトの名無しさん:2005/10/16(日) 00:15:24
なんかもう凄く>>943なのでC++1から勉強し直した方が身のため
949デフォルトの名無しさん:2005/10/18(火) 01:11:22
>927
とりあえずLokiのSingletonで我慢しときなさい。
そういや、BoostのSingletonてどうなったんだろう?
950デフォルトの名無しさん:2005/10/18(火) 10:45:59
(^^;
951デフォルトの名無しさん:2005/10/18(火) 10:47:07










(^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^;

 (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^;

(^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^; (^^;
952デフォルトの名無しさん:2005/10/18(火) 10:49:39



     (^-^;) (^ ^;) (^ω^) (^_^;)


953デフォルトの名無しさん:2005/10/18(火) 15:35:38
おでかけレスター
954デフォルトの名無しさん:2005/10/19(水) 20:35:37
れれれのれ(^^;
955デフォルトの名無しさん:2005/10/19(水) 23:59:13
「憂鬱本」読んだりして何とかオブジェクト指向については
わかってきた感じ。
でもデザインパターンについてはさっぱりだ。
デザパタの勉強するのにC++よりJavaの方がいいんでしょうか?
GoF見てわからない人は読むべしって本もJavaの本でしたし…
もしかしたらスレ違いかもしれませんが、よかったらアドバイス
お願いします。

元々コボラーな俺だけど、最近はSQLとかC、Perlなんかも少しづつ覚
えてきたよ。もうちょっとPerlは勉強したい。
本当はC++を勉強したい気持ちがあるんだが、デザパタ習得する近道
がJavaにあるならやってみたい。
956デフォルトの名無しさん:2005/10/20(木) 23:58:24
>>955
コボルでやればいいんじゃない?
957デフォルトの名無しさん:2005/10/21(金) 00:20:34
(^ω^) Javaのほうがいいよ (^ω^)
958955:2005/10/21(金) 05:22:23
>>956
さすがにCOBOLでデザパタはないですよw

>>957
なんとなっくオブジェクト指向にしろデザインパターンにしろC++より
Javaのほうが入りやすいのかなぁと思ってます。
やっぱりJavaで勉強していくほうを検討してみます。ありがとうござい
ました。
959デフォルトの名無しさん:2005/10/21(金) 08:25:04
デザパタがわかるとかデザパタを勉強するとか言う言葉に猛烈な違和感を覚える。
960デフォルトの名無しさん:2005/10/21(金) 12:30:02
>>959 同意
「GoFが××パターンと呼ぶ設計です」
なら違和感はないけどね
961デフォルトの名無しさん:2005/10/22(土) 16:40:04
>>959
たとえばGoFについてはOOPのイディオム的な部分じゃない?
「わかる」・・・その局面に適用する理由がわかる
「勉強する」・・・知識としてしっておく
OOPを習得する近道として違和感のある言葉じゃないと思う
962デフォルトの名無しさん:2005/10/22(土) 18:48:52
>>961
なるほどなるほど。君の言いたい事は、痛いほどわかったぞ。
963デフォルトの名無しさん :2005/10/23(日) 05:24:44
>>958
Javaの方が良い
C++だと余分な煩雑な言語仕様が多過ぎる
後、継承とインターフェースの分離・違いが解り易い
極端な話、インターフェース中心に考えると、デザパタに帰着する
964デフォルトの名無しさん:2005/10/23(日) 09:51:20
>>963
実装継承できないのが('A`)マンドクセ
実装継承分の委譲コード、コード自動生成してくれるツールでもあればいいのに・・・
965デフォルトの名無しさん:2005/10/23(日) 09:53:34
>964
Eclipseは?
966955:2005/10/24(月) 06:12:20
>>956 >>957 >>959-963
アドバイスありがとうございました。
もう少しPerl勉強したらJAVAにやってみようかと思います。
とりあえず、Eclipse入れて@ITにある入門はやってみました。

>>959 >>960
まず、デザパタとはなんぞやってところからわかってないので、おかしな
質問すみませんでした。

コボラーの私ですが、好きでやってるものですから、何とか新しいものに
はなされないようにがんばってみようと思います。

本当にありがとうございました。
967デフォルトの名無しさん:2005/10/28(金) 16:17:01
的外れなことを書いていたらすみません。Factory Methodパターンの質問です。
以下のように生成されるクラスの実行結果によって
次に処理を行うクラスが決定される場合、
(xClass内でxxBean.setNextClassNameメソッドにより次の生成クラスを決定)

while(xxBean.getEndflag){
  switch(xxBean.getNextClassName()){
    case Aclass:
      Aclass a = new Aclass();
      a.execute(xxBean);
      break;
    case Bclass:
      Bclass b = new Bclass();
      b.execute(xxBean);
      break;
    case Zclass:
      Zclass z = new Zclass();
      z.execute(xxBean);
      xxBean.setEndflag(false);
      break;
  }
}
968967:2005/10/28(金) 16:18:24
Factory Methodパターンを適用すると

while(xxBean.getEndflag){
  switch(xxBean.getNextClassName){
    case Aclass:
      Factory aFactory = new Factory();
      AProduct aProduct = aFactory.create();
      aProduct.execute(xxBean);
      break;
    case Bclass:
      Factory bFactory = new Factory();
      BProduct bProduct = bFactory.create();
      bProduct.execute(xxBean);
      break;
    case Zclass:
      Factory aFactory = new Factory();
      ZProduct zProduct = zFactory.create();
      zProduct.execute(xxBean);
      xxBean.setEndflag(false);
      break;
  }
}
のように、生成されるクラス毎にFACTORYとPRODUCTの実装クラスを
定義する必要があるのでしょうか?なんだかクラスがいっぱいできてメンテナンスが大変そう
なんですがそういうものなんですよね?認識があっているか不安です。
969デフォルトの名無しさん:2005/10/28(金) 18:13:32
これ FactoryMethod つかう必要が無くないか?
970969:2005/10/28(金) 18:28:32
うん。っていうか FactoryMethod じゃなくて、むしろ AbstractFactory だなコレは。
AbstractFactory で考えるけど、
 ・AProduct, BProduct, CProduct を abstract class Product から継承し、インターフェイスを共通化する
 ・↑の製品を作る AFactory, BFactory, CFactory を abstract class Factory から継承し、インターフェイスを共通化する
んでついでに xxBean.getNextClassName() じゃなくて xxBean.getNextFactory() にすると

while(xxBean.getEndflag){
    Factory factory = xxBean.getNextFactory();
    Product product = factory.create();
    product.execute(xxBean);
}

となるので見た目はスッキリ。
しわ寄せがどこかに行くから、ちゃんと使いどころを見定めてな。


ちなみに、生成されるクラスごとに Factory と Product を作らなきゃいけないのは合ってる。
ただ、幾ら作っても Factory と Product の扱い方を知ってるだけで良い、というのが Factory 系パターンの利点。
971967:2005/10/28(金) 18:45:48
>>968,>>969さん
どうもありがとうございます。
factoryパターンを適用するとswitch文のネストを使わないで、
オブジェクト指向的に生成するクラスを変化できると聞いてやってみるも、
いまいちメリットが納得できませんでした。さらにclassForNameを追加して、
switch文のネストをなくそうともしてましたが、本末転倒ですね。

AbstractFactoryなんですね・・・。
そして、自分の書いたソースがなんとカッコ悪いこと。
ありがとうございます。
972967:2005/10/28(金) 20:01:43
すみません再度質問です。聞いてばかりですみません。

各々xProductの実装クラスの中で、xxBean.setNextFactory(new xFactory());
を実行し、次の実行クラスを設定すると思います。

この際、xxBean.getNextFactoryメソッドの引数となるxFactoryのインスタンスは
動的に設定しようとした場合、リフレクションになってしまうんですよね?

実行速度を求めた場合、xProductは複数存在するのでユーティリティクラスを作成し、
その中でswich文を使用し、xFactoryの種類を判断/インスタンスの返却をするのが良いのかな・・
973967:2005/10/28(金) 20:03:12
誤記があったので訂正します。
誤:この際、xxBean.getNextFactoryメソッドの引数となる
正:この際、xxBean.setNextFactoryメソッドの引数となる
974デフォルトの名無しさん:2005/10/28(金) 20:26:21
う〜ん……。Factory 系が良くわかって無い予感。

    public void setNextFactory(Factory f) { }

として setNextFactory を定義。

    public abstract class Factory {
        public abstract Product create();
    }
    public class AFactory extends Factory {
        public Product create() { return new AProduct(); }
    }
    public class BFactory extends Factory {
        public Product create() { return new AProduct(); }
    }
    public class CFactory extends Factory {
        public Product create() { return new AProduct(); }
    }

とやっておけば、setNextFactory する側が

    setNextFactory(new AFactory());
    setNextFactory(new BFactory());
    setNextFactory(new CFactory());

という風に、どの Factory をセットするか選ぶだけで良い。
975デフォルトの名無しさん:2005/10/28(金) 20:31:17
逆に言うと、

    class AFactory extends Factory
    class BFactory extends Factory
    class CFactory extends Factory

    class AProduct extends Product
    class BProduct extends Product
    class CProduct extends Product

と定義 "できない" 場合、
または各インスタンスを Factory と Product として統一的に扱うことが "できない" 場合には
AbstractFactory は "使わないほうが" 良い。


あと、setNextFactory で Factory を入れるくらいなら、最初から Product をセットするべきかもと思った。
976デフォルトの名無しさん:2005/10/28(金) 20:39:36
ごめん。>>974 だと BFactory も CFactory も AProduct 作ってたわ。
977967:2005/10/28(金) 20:57:15
>>974,>>975,>>976さん
説明が下手でごめんなさい。

>とやっておけば、setNextFactory する側が
>
> setNextFactory(new AFactory());
> setNextFactory(new BFactory());
> setNextFactory(new CFactory());
>
>という風に、どの Factory をセットするか選ぶだけで良い。

この部分でのどの Factory をセットするかの実装方法について再度
お聞きした感じです。xProductを利用する側はAbstruct Factoryの導入で
インスタンスの生成を動的に行えますが、setNextFactoryも同じように
楽に(switch文ネストで候補をずらずらかかない感じに)できないのかなと思いまして。
978デフォルトの名無しさん:2005/10/28(金) 21:06:04
>>967 の例と比較するけど、プログラム上で行う場合には

setNextClassName("Aclass");
setNextClassName("Bclass");
setNextClassName("Zclass");

setNextFactory(new AFactory());
setNextFactory(new BFactory());
setNextFactory(new ZFactory());

これらに差があるとも思えない。


もし、ユーザ側からクラス名を受け取り、そのインスタンスを作成したいのならば
リフレクションまたは switch 文が確実。
979967:2005/10/28(金) 21:28:20
>もし、ユーザ側からクラス名を受け取り、そのインスタンスを作成したいのならば
>リフレクションまたは switch 文が確実。

その言葉、重いです・・・。
setNextClassName("Aclass");
setNextFactory(new AFactory());
に差がないのならば、メンテナンス性を考えると
GOF適用しないほうが良いのかな・・・。悩んできた。
980デフォルトの名無しさん:2005/10/28(金) 22:16:28
いまさらだけど、ハッシュテーブルという便利なものを思い出した。
クラス名を表す文字列をキーに、Factory クラスやら目的クラスのインスタンスを入れておいて、
そこから引っ張り出して使うとか。
981デフォルトの名無しさん
>>980
DI