Javaで同じ処理内容のメソッドをまとめる方法について

このQ&Aのポイント
  • Javaで同じ処理内容のメソッドを効果的にまとめる方法について教えてください。Template Methodパターンではクラス数が膨大になってしまうため、クラスを増やさずに済む方法があるか知りたいです。
  • Javaで同じ処理内容のメソッドをまとめる方法について教えてください。例外処理を共通部分で行い、処理が異なる部分のみを実装したいです。
  • Javaで処理内容がほぼ同じメソッドを効率的にまとめる方法について教えてください。Template Methodパターンではクラス数が増えるため、できるだけクラスを増やさずに済む方法を知りたいです。
回答を見る
  • ベストアンサー

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

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

  • amer1
  • お礼率81% (9/11)
  • Java
  • 回答数4
  • ありがとう数4

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

  • ベストアンサー
  • teketon
  • ベストアンサー率65% (141/215)
回答No.3

TemplateMethodで対象処理メソッド数が、極端に増えるときは設計がおかしいと思ったほうがいいです。 どうしてもTemplateMethodでちょっとずつ違う処理が必要な場合、後で使う側は結局ソースの中身を知ってないといけなくなります。20種類も読んで差異を把握するのは、ほぼ無理です。 そういう時は、分かりやすいクラスで分けてしまって、FactoryMethodで提供側で自動切り替えするといいです。 クラス数が膨大になってもいいと思いますよ。

amer1
質問者

お礼

なるほど、FactoryMethodパターンですか。 存在自体は知っていましたが、こういった際に使うと便利なのですね。 とても参考になりました。 ありがとうございました。

その他の回答 (3)

回答No.4

処理Cを別メソッドとして切り出すだけだと思います。 ちなみに Template Method パターンは処理の骨組みを 共通化して、肉づけを実装するという、いわゆるフレームワーク とか「上位の共通化」に用いるもので、 処理の一部の共通化(下位の共通化)には使いません。 もし、抽象クラスで共通の例外処理を提供し、それを 各具象クラスで利用するというパターンに直せるなら Template Method パターンが使えるかもしれません。 単に同一のクラス内で例外処理が同じメソッドが複数あるだけの場合は Template Method は不適切です。

amer1
質問者

お礼

Template Methodパターンの使い方を誤解していたようです。 確かに今回のパターンですと、処理Cを切り出すだけの方がよさそうですね… とても勉強になりました。 他の方に教えて頂いたのですが、Factory Methodパターンで書くと綺麗に書けそうですので、 そちらで実装を行いたいと思います。 ご回答いただき、ありがとうございました。

  • root139
  • ベストアンサー率60% (488/809)
回答No.2

質問内容を見ただけだと、単に処理Cの部分を別のメソッドに切り出せば良いように思えますが・・・。 例) ------------------------------------ // メソッドA public void A(){ try{ // 処理A; } catch (Exception e){ execC(); } } // メソッドB public void B(){ try{ // 処理B; } catch (Exception e){ execC(); } } private void execC() { try{ // 処理C; } catch(Exception e1){ e1.printStackTrace(); } } ---------------------------------------- 恐らく、そうは出来ない理由があるのだと思いますが、もう少し具体的な状況が分からないと何とも・・・。

amer1
質問者

お礼

ご回答いただきありがとうございます。 少し例が悪かったのですが、今回の例で言う、処理A,処理Bの周辺にかなり面倒な処理(共通処理)が混ざっているような場合についてどのようにしたらよいか、というご相談でした。 後の方に教えていただきましたが、Templateメソッドパターンを使うとよさそうですので、そちらを利用しようと思います。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

メソッドA、Bを変数で渡し、 リフレクションを使って 実行したらどうでしょう。 でも1メソッドくらいなら、 個別に書いてもと思います。 例外時の処理は共通化されて いるんでしょ? リフレクションって、面倒臭いん ですよね。 「リフレクション」「動的メソッド実行」 のようなキーワードで検索すると、 サンプルが見つかります。

amer1
質問者

お礼

ご回答いただきありがとうございます。 リフレクションは初めて知りました。 調べてみるとなかなか面倒そうですが、Stringから対応したメソッドが起動できる等、なかなかおもしろい仕組みですね。 今後の参考にさせて頂きます。

関連するQ&A

  • Strategyパターンを用いた実装について

    Strategyパターンを用いた実装について 現在Javaを勉強しており、 Strategyパターンを用いた以下の実装を考えています。 public class UseStrategy { private Strategy strategy; public void doSomthing(int num) { switch (num) { case 0: strategy = new AlphaStrategy(); break; case 1: strategy = new BetaStrategy(); break; case 2: strategy = new GammaStrategy(); break; } // 変数strategyを用いて処理を続行していく // ... } private interface Strategy { public abstract void method_1(); public abstract void method_2(); } private class AlphaStrategy implements Strategy { @Override public void method_1() { //do something } @Override public void method_2() { //do something } } private class BetaStrategy implements Strategy { @Override public void method_1() { //do something } @Override public void method_2() { //do something } } private class GammaStrategy implements Strategy { @Override public void method_1() { //do something } @Override public void method_2() { //do something } } } つきましては、以下ご質問させてください。 (1)Strategyパターンの実装において、  上記UseStrayegyクラスのように、あるクラスの入れ子クラスとして  Strategyインターフェース及び、その実装クラスを実装する方法は  普通でしょうか?    それとも、入れ子クラスとしてではなく、Strategyインターフェース、  その実装クラスを全て 別クラスファイルに分けた方が良いのでしょうか? (2)例として、  BetaStrategy.method_2()とGammaStrategy.method_2()の処理が全く  同じだったとします。その場合、共通となる処理を一つのメソッド化し、  そのメソッドをBetaStrategy.method_2()とGammaStrategy.method_2()から  コールしたいと考えております。  その際、共通となる処理メソッドの実装箇所としては、以下のいずれが良いのでしょうか。   (A)Strategyインターフェースを抽象クラス化し、二つの共通処理メソッドを実装する。  (B)UseStrategyクラスに、共通処理を実装する。    それとも、上記の様なケースがある場合Strategyパターンは不適切でしょうか。 文面に分かりづらい面や、Javaのオブジェクト指向・デザインパターンについて 理解の乏しいところがあるかと思いますが、ご回答の程よろしくお願いいたします。

    • ベストアンサー
    • Java
  • テンプレートメソッド

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

    • ベストアンサー
    • Java
  • 継承したメソッドのドキュメンテーションコメント

    C#の開発を始めて日が浅いため、現場におけるお作法がわかりません。 現場におけるクラス・インターフェースを継承したメソッドのドキュメンテーションコメントの付け方に関する一般論についてお教えいただきたいです。 ※基底クラス、及びインターフェースの抽象メソッドにはドキュメンテーションコメントの記述がある物とします。 ※普段はJavaを使っている為、そこから引用している書いている部分があります。ご容赦下さい。 ・抽象クラスにおけるインターフェースから継承した抽象メソッド(実装しない場合) Javaとは違い、抽象クラスであってもインターフェースが持つの抽象メソッドを無視する事はできず、 public abstract修飾子を付けて抽象メソッドを定義してやる必要があるようなのですが、 この場合、ドキュメンテーションコメントは省略すべきでしょうか? それとも、何かしら記述するべきなのでしょうか?(Javaで言うところの@inheritDoc等・・・そのような物があるかはわかりませんが) ・新たに実装を行う場合(抽象メソッドの実装等) 省略すべきでしょうか? ・既存の実装を拡張し、変更の影響は微小かつメソッド内のみで完結し、概要やその他のメソッドの責任において表記すべき内容に変化が無い場合 省略すべきでしょうか? ・既存の実装を拡張し、想定される例外の追加等、メソッド外にも影響を及ぼす大きな変更が入った場合 新たに完全なドキュメンテーションコメントを作成するべきでしょうか? それとも差分以外は新たに作成すべきではないのでしょうか? 一般論と言っても規模や進め方によって様々だとは思いますが、 通念的に「心がけていくべき事」等あれば、是非お教え下さい。 最後に、この質問の趣旨からは外れるのですが、一つ追加で別の質問をさせてください。 私は何故抽象クラスがインターフェースの抽象メソッドを無視できないかがわかっておりません。 (インターフェース-インターフェース、抽象クラス-抽象クラスは無視できるのに) 敢えて明示的に定義を強要させている以上、何か理由あっての事だと思いますが、 それがわからず悶々村々としながら作業しております。 その理由をお教えいただけませんでしょうか。 宜しくお願い致します。

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

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

    • ベストアンサー
    • Java
  • メソッドの中でインスタンス化が行われているとき。

    javaを学習している者です。 下記のような記述があったのですが、これはどういった処理になるのでしょうか?インスタンス化した時に{};をくっつけているところが分かりません。 protected boolean checkAnswer(){ EachCellOpe checkOp = new EachCellOpe(){//EachCellOpeは抽象クラス //この中にいくつかのメソッドが実装される };//←この「;」は!? } よろしくお願いします。

    • ベストアンサー
    • Java
  • 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
  • printStackTrace()メソッドに関する疑問

    お世話になります。 Javaの例外処理等で使用されるprintStackTrace()メソッドに関する疑問なのですが・・・。 AppletやServletのプログラム内の例外処理で使用されるprintStackTrace()メソッドは通常例外が発生すると、ログ等に例外メッセージが表示されますが、printStackTrace()メソッドで取得した例外メッセージをHTMLで画面表示させる事は(エラーメッセージや例外メッセージが発生した時にそのメッセージをHTMLで画面表示させる様にするという処理を行う場合)出来るのでしょうか? getMessage()メソッドでは上手くメッセージを取得して変数に格納し、HTMLでメッセージを画面表示させるようには出来るのですが、printStackTrace()メソッドでは上手く出来ません。 ご存知の方がいらっしゃいましたら、是非ご教授お願い致します。

    • ベストアンサー
    • Java
  • javaで、オブジェクトを生成しないとメソッドは使えないんですか?

    javaで、オブジェクトを生成しないとメソッドは使えないんですか? そのように習ったのですが、サブクラスのメソッド定義の中で、オブジェクトを生成せずにスーパークラスのメソッドを使える例(下に簡単に書きました)をみて、分からなくなってしまいました。 おしえてください、よろしくおねがいします。 ------------------------------- class superclass { method_a(){ ~~~~ } } --------------------------- class subclass { method_b(){ super.method_a(); }

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

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

    • 締切済み
    • PHP
  • Javaの例外処理の書き方について

    Javaの例外はErrorとRuntimeExceptionは書かなくてもいいが、 Exceptionはtryでcatchする必要があると聞きました。 しかし、java.langのStringを使っても例外処理は書きません。 なぜ、例外を書くやつと書かないやつがあるのですか? たとえば、java.langを使うとしたら、 ClassNotFoundException CloneNotSupportedException Exception の3つをjava.langを使うメソッドのブロックの上にtry文が必要だと思うのですが。

    • ベストアンサー
    • Java

専門家に質問してみよう