- PR -

デザパタ練習問題で。。。

投稿者投稿内容
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-09-02 17:18
おわびに、あんど、yamasaさんの補足
コード:
abstract class Sample implements ISample
{
  private ISamethingC _iC;
  protected abstract void doSamethingB();
  public void setSamethingC(ISamethingC newISamethingC)
  {
    _iC = newISamethingC;
  }
  protected final void trace(){ _iC.trace(); }
  public void doSamething()
  {
    /* 処理A */
    /* 処理B */
    doSamethingB();
    /* 処理C */
    trace();
    /* 処理D */
  }
}



処理を独立に切り替えないのであれば、Template Methodが使えると思いますが、その場合は以下の様になるでしょう
コード:
abstract class Sample implements ISample { 
    public void doSomething() {
       doSomethingA();
       doSomethingB();
       doSomethingC();
       doSomethingD();
    }

    protected abstract void doSomethingA();
    protected abstract void doSomethingB();
    protected abstract void doSomethingC();
    protected abstract void doSomethingD();    
}



しかしこの場合、以下のようにStrategyを使用する方針も考えられます。
コード:
abstract class Sample implements ISample { 
    SampleStrategy mStrategy;

    protected Sample(SampleStrategy inStrategy) {
        mStrategy = inStrategy;
    }

    public void doSomething() {
        mStrategy.doSomethingA();
        mStrategy.doSomethingA();
        mStrategy.doSomethingB();
        mStrategy.doSomethingC();
        mStrategy.doSomethingD();
    }
}

interface SampleStrategy {
    public void doSomethingA();
    public void doSomethingB();
    public void doSomethingC();
    public void doSomethingD();    
}



使い分けは、yamasaさんが言われているように、
引用:

Template Method パターンを適用する場合は、そのクラス本来の目的に関係する
重要な部分1箇所までにしておき、残りの交換可能な部分は Strategy パターンで
実装するのが良いのではないかと思います。


を、基準にすれば、再利用性の高いコンポーネントを設計できるでしょう。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-09-02 17:32
ども、ほむらです。
--------
yamasa氏へ
引用:

かずくんさんの挙げられた例が、私の意図していたものとほぼ同じですね。

ここでのキモは、

(1)
交換可能にする部分がシンプルな1メソッドだけならば、
Strategy パターンよりも Template Method パターンのほうが
見た目はシンプルになる。

(2)
複数のメソッドを独立に交換可能にしようとすると、
とたんに Template Method パターンは破綻してしまう。

ということです。
Template Method パターンを適用する場合は、そのクラス本来の目的に関係する
重要な部分1箇所までにしておき、残りの交換可能な部分は Strategy パターンで
実装するのが良いのではないかと思います。


(a)の部分をTemplate Methodパターンで作っていた場合、(b)を作るのは
手間がかかってしまっていたかもしれませんね。。(作り直しにちかいかも?)
ということで、練習問題をやってみた感じとしては、
Strategyパターンを基本にして作っていって処理的なものでまとめる。
そうすると、きれいにさっぱりしたコードになりやすいということですか、、、


あと、
いまだに委譲について調べてなかったりしますが^^;;;、感覚的に
Template Method には委譲と言う行為も含まれているのではないかと思います。
個人的には
操作の実体をサブクラスに任せた処理(流れ)の雛型である。
なんてまとめてしまっています。

でも、単一インスタンス内でというのが、ISamethingCにアクセスしていることが
いけないというのならば、僕が考えていたことよりももっと小さいものなのかも。。。

参考URL:
デザインパターン入門 Template Methodパターン

かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-09-02 18:07
引用:

いまだに委譲について調べてなかったりしますが



私も正確な定義がわからないので、出来る限り使用せず、たらい回しとかいってお茶を濁しています。

書籍によって、定義がまちまちで、
ある書籍では、自身で処理できないことを、ラップしているコンポーネントに転送することを委譲といったり、
また別の書籍では、これは委譲とはいわず、転送時、自身の参照を渡した場合が委譲だとか、ホントどれを信じて良いのか分かりません。
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-09-03 01:49
とりあえず「UMLリファレンスマニュアル」には、委譲について
引用:

メッセージに応答してオブジェクトが別のオブジェクトにメッセージを発行する能力。


と書いてありますね。
委譲先はラップしているオブジェクトでなくても構わないようです。

私の場合は、
「あるオブジェクトが自身の責務(の一部)を別のオブジェクトに転送すること」
なんて説明をすることが多いです。

委譲先オブジェクトの取り替えにより処理内容を変化させる Strategy パターンと、
メソッドのオーバーライドにより処理内容を変化させる Template Method パターン
というように対比させることができるでしょうか。

ところで、
引用:

かずくんさんの書き込み (2003-09-02 18:07) より:
また別の書籍では、これは委譲とはいわず、転送時、自身の参照を渡した場合が委譲だとか、


これって何という書籍でしょうか?
私が知っている範囲では、"Effective Java"がこのような記述をしていますが、
おそらくこれは間違いでしょう。
"Effective Java"ではその根拠としてGoF本を参考文献に挙げていますが、
GoF本には「自身の参照を渡さない場合は委譲とは言わない」なんて記述はありません。
"Effective Java"の著者の勘違いだと思います。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-09-03 13:45
引用:

これって何という書籍でしょうか?
私が知っている範囲では、"Effective Java"がこのような記述をしていますが、
おそらくこれは間違いでしょう。
"Effective Java"ではその根拠としてGoF本を参考文献に挙げていますが、
GoF本には「自身の参照を渡さない場合は委譲とは言わない」なんて記述はありません。
"Effective Java"の著者の勘違いだと思います。


おっしゃる通り、Effective Javaです。
私、GOF本を持っていないので、実際に確認したわけではないんです。
参考文献として指定されたページに記載がないということですよね。

これって、日本語に訳した段階で、訳者の理解が足らず、別の言葉に置きかえられたり、間違った訳を与えたということはないのでしょうか。
つまり原文(英語?)には間違いなく書かれているということはないのでしょうか。
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-09-03 14:18
ども、ほむらです。
-----------------
かずくん氏へ
Strategy パターンってかなり強力ですね。。。
欠点は切り替えるという関係で粒度が微細になりやすいという程度ですか。
粒度の問題に関してはデザインパターンすべてに当てはまりそうな感じもしますね。

よかったら参考までに聞かせてください。
粒度が小さく多くのクラスやメソッドが作られていくことかと思いますが
ソースコード上ではどういったまとめ方をされますか?
もう少し直接的に言えば宣言時にできるなんらかの工夫はありますか?といった感じです。

yamasa氏へ
引用:

とりあえず「UMLリファレンスマニュアル」には、委譲について
引用:

メッセージに応答してオブジェクトが別のオブジェクトにメッセージを発行する能力。


と書いてありますね。
委譲先はラップしているオブジェクトでなくても構わないようです。

私の場合は、
「あるオブジェクトが自身の責務(の一部)を別のオブジェクトに転送すること」
なんて説明をすることが多いです。


別の質問になってしまいますが
ラップしているオブジェクトでなくても良いということは
AdapterパターンやDecoratorパターンも委譲の関係にあると思ってよいのでしょうか。。
(クラスの参照を渡して内部で色々とやる形とか)

引用:

委譲先オブジェクトの取り替えにより処理内容を変化させる Strategy パターンと、
メソッドのオーバーライドにより処理内容を変化させる Template Method パターン
というように対比させることができるでしょうか。


わかり易い表現だと思います。使わせていただきます。
メモメモっと(笑
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-09-03 16:58
引用:

よかったら参考までに聞かせてください。
粒度が小さく多くのクラスやメソッドが作られていくことかと思いますが
ソースコード上ではどういったまとめ方をされますか?
もう少し直接的に言えば宣言時にできるなんらかの工夫はありますか?といった感じです。



参考までに、粒度の観点に関して、私の開発方針を。
規模が大きくなりそうなGUIアプリケーションの場合、個人的に好きなBCE(Boundary-Controller-Entity)パターンでLayer分けし、各Layerは中粒度程度に抑えます。もし粒度が微細になるようなら、そのLayerを再度分割したり、Facardパターンにより新たなLayerを作成して、各Layerが中粒度になるように保ちます。ただ、よっぽど大規模なものでない限り、再分割が必要になることはないと思います。

# 正確にはBCEはLayerパターンに属するのだったかな

また、Strategyを多用すると、継承階層は浅くなるが面方向への広がり(クラス数)はどうしても多くなってしまいます。

あまり無理してデザインパターンを適用しようとはせず、インターフェースと実装の分離することを中心にやっていけば、意図していなくても、デザインパターンのいずれかに近づいていきます。
yamasa
ベテラン
会議室デビュー日: 2003/02/15
投稿数: 80
投稿日時: 2003-09-04 02:03
引用:

かずくんさんの書き込み (2003-09-03 13:45) より:
引用:

これって何という書籍でしょうか?
私が知っている範囲では、"Effective Java"がこのような記述をしていますが、
おそらくこれは間違いでしょう。
"Effective Java"ではその根拠としてGoF本を参考文献に挙げていますが、
GoF本には「自身の参照を渡さない場合は委譲とは言わない」なんて記述はありません。
"Effective Java"の著者の勘違いだと思います。


おっしゃる通り、Effective Javaです。
私、GOF本を持っていないので、実際に確認したわけではないんです。
参考文献として指定されたページに記載がないということですよね。

これって、日本語に訳した段階で、訳者の理解が足らず、別の言葉に置きかえられたり、間違った訳を与えたということはないのでしょうか。
つまり原文(英語?)には間違いなく書かれているということはないのでしょうか。


いや、原文でも同じです。

で、ちょっと調べていたら以下のようなトピックが見つかりました。
http://forum.java.sun.com/thread.jsp?forum=425&thread=427568&tstart=30&trange=15
向こうでも混乱している人がいるようです。

引用:

ほむらさんの書き込み (2003-09-03 14:18) より:
引用:

とりあえず「UMLリファレンスマニュアル」には、委譲について
引用:

メッセージに応答してオブジェクトが別のオブジェクトにメッセージを発行する能力。


と書いてありますね。
委譲先はラップしているオブジェクトでなくても構わないようです。

私の場合は、
「あるオブジェクトが自身の責務(の一部)を別のオブジェクトに転送すること」
なんて説明をすることが多いです。


別の質問になってしまいますが
ラップしているオブジェクトでなくても良いということは
AdapterパターンやDecoratorパターンも委譲の関係にあると思ってよいのでしょうか。。
(クラスの参照を渡して内部で色々とやる形とか)


Adapter や Decorator も委譲を用いたパターンと言えるでしょう。
# Adapter パターンには(多重)継承を使ったバージョンもありますが。

スキルアップ/キャリアアップ(JOB@IT)