• ベストアンサー

テンプレートメソッド

デザインパターンを使わずに書く方法とかって どんな感じなんになるんでしょう? たとえば、うどんをそばを作る場合なんかはほとんど 工程は一緒なのでテンプレートメソッドに使うんだろうけど みなさんならどうやって書きますか? ifとかならわかるんですが、もっとスマートにかけないものですか? 1どんぶり用意(親クラス) 2うどんかそばを入れる←重複するコード(実装を子クラスへ) 3だしをそそぐ(親クラス)

  • Java
  • 回答数3
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
noname#49664
noname#49664
回答No.1

まずは、基底となる抽象クラスとインターフェイスを定義しますね。必要となる要素を搾り出し、それらの性質を抽象クラスとして定義しておきます。 ・「麺」抽象クラスを定義 ・「うつわ」抽象クラスを定義 ・「だし」抽象クラスを定義 で、実際の利用には、それぞれのクラスを実装する。 ・「麺」クラスを継承し、「うどん」および「そば」クラスを定義。 ・「うつわ」クラスを継承し、「どんぶり」クラスを定義 ・「だし」クラスを継承し、「関東風だし」クラスを定義 ここまでがクラス類の用意。これらを利用してうどんやそばを作る際には、これらを利用するクラスを書く。例えば、立ち食いそばを作る際には、「立ち食いそば」クラスを定義し、そのコンストラクタに、「そば」、「どんぶり」「関東風だし」のインスタンスをそれぞれ引数として渡すようにしておきます。 new 立ち食いそば(new そば(),new どんぶり(),new 関東風だし()); こんな具合にして、立ち食いそばインスタンスを作るわけですね。 私だったら、だいたいこんな感じで実装するかな、と思います。もっと考えれば、例えば「作成」部分はインターフェイスとして定義しておき、「立ち食いそば」クラスにimplementsして使えるようにしたほうが便利かな? あるいは、インスタンスを生成するためのクラスやメソッドを用意するとか。(デザインパターンでいえばファクトリーというやつです) 要するに、要素を部品として分解し、汎用性を持たせる。そして抽象部分を抽出してそれを元に全体の実装を定義するようにする、という感じでしょうか。そう考えると、これは「デザインパターン」の考え方とさほど違いはないかも知れません。 デザインパターンというのは、なにか特殊な手法があるわけじゃなくて、多くの人があれこれ試行錯誤した末に「こうするのが一番いいんじゃないかな」とたどり着いたものがパターン化されたものですから。どんなことであれ、突き詰めれば、いずれはそこにたどり着くんじゃないでしょうか。

ilsole_
質問者

補足

丁寧な回答ありがとうございます。 とても参考になります! ・「麺」クラスを継承し、「うどん」および「そば」クラスを定義。 ・「うつわ」クラスを継承し、「どんぶり」クラスを定義 ・「だし」クラスを継承し、「関東風だし」クラスを定義 上記のように継承してクラスを作る意味ある(他にも処理が異なる)場合は、そうすると思うのですが。 下記のような「Selectmen」以外は処理が同じであった場合、テンプレートメソッド使って書くと以下のような書き方(抜けはあるかもしれませんが)になると思います。JavaのところにC++でコードを書くのはいかがなものかと思いますが・・それはお許しを。。 このような場合にテンプレートメソッドを使わないとなると 派生クラスを作る意味がないような気がして。 ですが、基本クラスでif”うどん”or ”そば”って分けるのはあまりに単純で。。 それ以外の方法でなにかないかと考えたのですが、あまりいいのが思いつかなかったために質問してみました。 class 麺 { protected:  virtual void Selectmen()=0; // 麺を入れる 抽象メソッド public:  昼食を作る()  {    どんぶりを用意する    Selectmen();    だしを入れる  } } class そば : public 麺 {  void Selectmen()  {    そばをどんぶりにいれる  } } class うどん : public 麺 {  void Selectmen()  {    うどんをどんぶりにいれる  } }

その他の回答 (2)

noname#49428
noname#49428
回答No.3

もしかして、Strategyパターンを理解していないのですか?

ilsole_
質問者

補足

出張で返事が遅くなりすみません! Strategyパターンはまだ勉強してません。。 今理解してるのは、以下の5個です。 Adaptor State Facade Template Command デザインパターンの本は手元にありますので一度読んで確認してみます。

noname#49428
noname#49428
回答No.2

TemplateMethodパターンの代替としては、Strategyパターンを使います。 継承を使うTemplateMethodより、委譲によるStrategyパターンのほうが好ましいです。

関連するQ&A

  • 処理内容がほぼ同じメソッドのまとめかたについて

    Javaにおいて、処理内容がほぼ同じメソッドを上手くまとめるにはどうすればよいでしょうか? もう少し具体的に説明をさせて頂きます。 例えば、以下の様なメソッドA, Bがあるものとします。 https://gist.github.com/4187704 この時、例外処理をしている共通部分を二重に書かず、処理が違う部分だけを実装するようにするにはどのようにすればよいでしょうか? というのが、質問の主旨になります。 色々調べた所、Template Methodパターンというものがあるのを知りましたが、自分の場合は、同様のメソッドが20個ほどあり、Template Methodパターンを使うとクラス数が膨大になってしまうため、なるべくクラスを増やさずに済む方法があれば教えていただきたいと思います。 よろしくお願い致します。

    • ベストアンサー
    • Java
  • templateメソッドパターンで抽象メソッドを定義する意義

    こんにちは。 テンプレートメソッドパターンで、例えば、 class oge { abstract function a(); abstract function b($param); final function tempMethod() { $this->a(); $this->b($param); } } とした場合、抽象メソッドの定義は意味があるのでしょうか? なぜなら、tempMethod()中でa()もb($param)も呼び出してますんで、 わざわざ抽象メソッドとして定義しなくてもサブクラスで実装しないとどっちみち動きません。 抽象メソッドの定義の意義を教えてください。

    • 締切済み
    • PHP
  • abstractメソッドの使い方

     漠然とした質問になりますが、よろしくお願いします。 今、前の人が記述したソースを読んでおりまして、 抽象クラスのメソッドの使い方で疑問が生じました。 lookメソッドに注目して頂きたいのですが、 public abstract class Editor { protected abstract boolean look() throws Exception; ・・・・・・・・・・・・ if(! this.look()) {   // ★ return false; } という記述があります。Editor クラスにはこの2つ以外のlookメソッドはありません。 そのためlook()では他のクラスで実装した戻り値が返ってくるはずですが、 thisを監視してデバックすると★の行上に処理のラインが来たとき、 thisにlookメソッドを含まないクラス名が表示されます。 thisがEditor でない事自体よく分かりません・・ abstractはあまり使ったことが無く、どこで実装されているのか(正確には、実装されているクラスのうちここで使われているのはどのクラスのlookメソッドか)を知りたいです。 知っている限りの方法では特定できませんでした。 よろしければアドバイスをお願いします。

    • ベストアンサー
    • Java
  • テンプレートの書籍

    テンプレートについて、学びたいと思っています。 当方、C++については、オブジェクト指向分析・設計から実装まで、 業務システム開発を、特に問題なく行っています。 デザインパターンも、ある程度は理解しています。 最近、テンプレートを趣味的に勉強しようと思いだしまして、 できるだけ平易なものを、楽しく読んでみたいと思っています。 そこで、こういう書籍をこういうステップで読んでいったら よい(よかった)など、教えていただければ幸いです。 面白く読めそうなWebサイトなどでも結構です。 ご紹介よろしくお願い致します。

  • オーバーライドしたメソッドで例外を投げたいとき

    お世話になります。 あるinterfaceを実装するクラスを作成しています。 そこでinterface内のメソッドを実装するわけですが、そこで例外を生成しthrowしたいと思っています。ですが、interfaceでそのメソッド定義にはその例外をthrowするようには定義されていないので、コンパイル時にエラーになります。 今は強引にNullPointerExceptionを生成するようなコードを書いて例外を発生させていますが、このようなケースではどのように記述するのが一般的なのでしょうか。 interfaceは内製ではないので変更することができません。 よろしくお願いいたします。

    • ベストアンサー
    • Java
  • テンプレートクラス内のテンプレートクラス(インナークラス)のメソッドを実装ファイルで定義したい

    現在、ヘッダファイル内で下記のようなクラスを宣言・定義しています。 // test.h template < typename T1 > struct A {   template < typename T2 > struct B   {     B( A const& arg ) { ... }   }; }; テンプレートクラスが入れ子になっていて、Bのコンストラクタが引数としてAを取っています。 しかし現状ではコンパイルがとんでもなく遅くなってしまうので、 Bのコンストラクタは宣言のみとし、別途実装ファイル(test.cpp)に定義を書きたいと思っています。 ところがメソッドのシグネチャをどう書けばよいのか分からなくなってしまいました。 苦し紛れに // test.cpp template < typename T1, typename T2 > A<T1>::B<T2>::B( A<T1> const& arg ) { ... } などと書いてみましたが、違うようです。 解決方法はありますでしょうか? 環境はVC7.1かVC8でコンパイルできればよいです。 よろしくお願いいたします。

  • ClientBase<TChannel> クラスの Dispose() メソッドについて

    お世話になっております。 http://oshiete1.goo.ne.jp/qa5572673.html に引き続き、 Dispose() メソッドの実装について不明な点があるので、よろしければご教示願います。 環境は、Visual C# 2008 Express Edition です。 .NET 3.5 まず、公開されているWebサービスに対して、 ソリューションエクスプローラより、サービス参照の追加で、Clientクラスを自動生成いたしました。 その自動生成されたクラス(仮に XSoapClient)が、System.ServiceModel.ClientBase<TChannel> クラスを継承しています。 ClientBase クラスは、IDisposable インタフェースを実装しているのですが、XSoapClient にも ClientBase にも、Dispose() メソッドの実装が見当たりません。 (自動生成のため、別の場所に作成されているのかもしれません。) using (XSoapClient client = new XSoapClient()) {  // ここにコード } とした場合に、client の Dispose() の実装がわからないため、 しっかりとコネクションが切れているのかが不明です。 Dispose() メソッド内では、Close() メソッドが呼ばれているのが普通なのでしょうか。 以上、よろしくお願いいたします。

  • 制御文がHTMLのコメントのテンプレートクラスってないですか?

    PHPには、ロジックとデザインの完全分離が行えて、ブラウザで開いてもIF文などの制御文がHTMLのコメント<!-- -->になっていて、デザインが崩れないSmarty等の素晴らしいテンプレートクラスがたくさんあるのですが、JavaにはVelocity等テンプレートクラスはたくさんあっても制御文がHTMLのコメントでない仕様の物しかないようです。どこかにブラウザで開いても綺麗に見えるJavaのテンプレートクラスはないでしょうか? 基本的には、IF、LOOP、LOOPのネスト、LOOP内のIFぐらいの機能があれば十分です。よろしくお願いします。

  • 「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」

    「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」は正しい? はじめまして。Javaのインタフェースに関する質問です。 私はこれまで、インタフェースを使うときは、インタフェースを実装してクラスを宣言し、そのクラス、またはサブクラスでインタフェースがもつすべての抽象メソッドを定義する、と理解していました。 しかし、下の例をみてください。抽象メソッドの定義を、インタフェースの実装の以前で与えています。問題無くコンパイルでき、実行できます。実行結果も以下の通りです。 インタフェースの抽象メソッドへの定義の与え方やその実行のされ方は、メソッドのオーバーライドと同様と思っていましたので、下記のコードでは「クラスBが抽象クラスではありません」や、「インタフェースの抽象メソッドがオーバーライドされていません」などの文法エラーがでると思っていました。 そこで、質問です。 インタフェースが持つ抽象メソッドの定義を与える場所について、または、これに関する説明のあるページなど、何かご存知でしたら教えてください。 ★コード★ interface X{   void show(); } class A{   public void show(){     System.out.println("A");   } } class B extends A implements X{ } public class Main{   public static void main(String[] args){     X x=new B();     x.show();   } } ★実行結果★ >java Main A ★Java環境★ java 1.6.0_21 javac 1.6.0_16

    • ベストアンサー
    • Java
  • Adapterデザインパターン

    Adapterデザインパターンは、 継承を利用した実装パターンと、 委譲を利用した実装パターンがあると思います。 http://www.techscore.com/tech/DesignPattern/Adapter/Adapter1.html/ 「親クラスにバグがあって修正した場合、  必ず子クラスも再コンパイルしなければならない」 ということを考えると、 保守性は高いのでしょうか?

    • ベストアンサー
    • Java