2013-04-26 23 views
6

私はいくつかの作業を実行するutilクラスを持っています。明らかに、それは拡張のために閉じられており、すべてのメソッドは静的です。簡略化のために、クラスは次のようになります。静的クラスのテンプレートメソッドパターン

public final class Util { 
    private Util() { } 

    public static void doWork() { 
     // some work 
     int variable = help(); 
     // some work uses variable 
    } 

    private static int help() { 
     // some helper functionality 
    } 
} 

クラスは、計算の多くを実行するメソッドdoWorkを持っています。ちなみに、メソッドはヘルパーメソッドhelpを呼び出していくつかの結果を取得し、残りのコードはhelpメソッドによって返された結果を使用します。

クライアントコードでは、メソッドdoWorkの機能を再利用したいが、helpを呼び出す代わりに、help2メソッドに電話したいと思う。最も簡単な解決策は、helphelp2に置き換えて、メソッドdoWork2を作成するだけです。

doWorkのすべての変更をdoWork2に複製する必要があるため、非常に悪い方法です。これはTemplate Methodパターンに非常に似ていますが、ここでは拡張子がないため、適用できません。

ベストソリューション私は、このメソッドにパラメータを追加しますが、doWorkのすべての既存のユーザーを維持するために思い付いた:

public static void doWork() { 
    doWorkWithParameter(true); 
} 

public static void doWorkWithParameter(boolean helpOrHelp2) { 
    // some work 
    int variable = helpOrHelp2 ? help() : help2(); 
    // some work uses variable 
} 

よりよい設計ソリューションは、この問題を解決するために適用することができていますか? Template Patternのような柔軟性を実現する方法はありますか?しかし、utilクラスのアプリケーションにはあります。

ありがとうございます。

+0

はあなたのソリューションのメソッドのオーバーロードを使用していない何らかの理由はありますか? 'public static void doWork(){...}' 'public static void doWork(boolean param){...}' – Crazenezz

+0

それ以上はまだ 'public static void doWork(int variable)'です。実際の答えは、混乱は静的に起因し、オブジェクトはより洗練された答えを提供すると考えられますが、抽象的な例ではわかりにくいです。 –

+0

あなたが探しているものは戦略パターンです。 Arnaldoの答えを確認してください。 –

答えて

5

私の提案はUtilのクラスが実行者および各doWorkヘルプ対であるCommand Pattern、に触発された労働者のインタフェースを使用してカプセル化されていますまたはあなたが行うことができます。

public class ConcreteWorker implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 

別のワーカー

ワーカーintefaceをがUtilのクラス

public final class Util { 
    private Util() { } 

    public static void toWork(Worker worker){ 
     worker.doWork(); 
    } 

} 

コンクリート労働者

public interface Worker { 
    public void doWork(); 
    public int help(); 
} 

のようないくつかの可能性があり(ヘルプとdoWorkの実装)

public class ConcreteWorker2 implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 1; 
    } 

} 

と実行

Util.toWork(new ConcreteWorker()); 
Util.toWork(new ConcreteWorker2()); 
+0

Workerインタフェースの代わりに、doWork()メソッドを使って抽象クラスとして作成するのがよいでしょう。これは実際に私が示唆しているものと同じですが、より多くのコードだけです。 1つではなく4つのクラスがあります。私はenumが静的メソッドのよりよい置き換えであると思います。 – Mikhail

+1

素晴らしい!それは、戦略パターン 'Collections.sort(lst、Comparator)'のように見えます。どうすればそれを逃すことができますか? – mishadoff

1

あなたはHelpインタフェースウィッヒを実装Help1 & Help2 2静的オブジェクトを作成することができ、ヘルプ()メソッドを持っており、このようなあなたのdoWorkWithParameter方法を変更します。

public static void doWorkWithParameter(Help h) { 
    int variable = h.help(); 
} 

それはあなたの現在のソリューションと密接に関連します。しかし、私はもう少し "オブジェクト指向"だと思う。その後、我々は呼び出すことができます

public static enum Helper{ 
    OLD(){ 
     public int help(){ 
      return 0; 
     } 
    }, 

    NEW(){ 
     public int help(){ 
      return 1; 
     } 
    }; 

    public abstract int help(); 

    public void doWork() { 
     int variable = help(); 
    } 
} 

public static Helper HELPER = Helper.NEW; 

Constants.HELPER.doWork() 

を私は動作を変更することができHELPER一定の値を切り替えることにより

1

ので、長い時間前、私はこれを作っているわけではありません。

Helper.OLD.doWork(); 
Helper.NEW.doWork(); 
+0

ありがとう、素敵なトリック。 – mishadoff

+0

これはEffective Javaの本です - 「Item 34:インタフェースで拡張可能な列挙をエミュレートする」 – Mikhail