2013-04-26 191 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方法。最簡單的解決方案就是創建方法doWork2,將help替換爲help2

這是非常糟糕的做法,因爲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

有沒有你不解決方案使用方法重載的原因嗎? '公共靜態無效的doWork(){...}'' 公共靜態無效的doWork(布爾PARAM){...}' – Crazenezz 2013-04-26 12:54:11

+0

或者更好的'公共靜態無效的doWork(int變量)'。雖然我懷疑實際的答案是,混亂是由於靜態和對象將提供更清潔的答案 - 很難說具有雖然抽象的例子。 – 2013-04-26 12:59:56

+0

你所尋找的是策略模式。檢查阿納爾多的答案。 – 2013-04-26 13:05:43

回答

5

我的建議是在Command Pattern,其中的Util類是祈求和各的doWork的幫助對使用的啓發工人接口封裝。

工人Inteface可以是某種象

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

使用util類

public final class Util { 
    private Util() { } 

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

} 

混凝土工人

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; 
    } 

} 

另一個工人

(幫助和的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

而是工人的接口,你最好把它作爲與的doWork()方法的抽象類。這實際上與我所建議的相同,只是更多的代碼。你有四個班而不是一個班。我猜想枚舉可以更好地替代靜態方法。 – Mikhail 2013-04-26 13:12:25

+1

太棒了!它看起來像戰略格局'Collections.sort(LST,比較器)'。我怎麼會錯過? – mishadoff 2013-04-26 13:16:00

1

你可以創建2個靜態對象Help1 & Help2實現Help接口至極有幫助()方法,改變你的doWorkWithParameter方法是這樣的:

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

它密切相關,當前的解決方案。但我認爲它更「面向對象」。

1

並非如此很久以前我有此:

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常數值我可以改變的行爲。或者你可以這樣做:

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

謝謝,好戲。 – mishadoff 2013-04-26 13:16:47

+0

這是有效的Java書 - 「項目34:效法擴展枚舉與接口」 – Mikhail 2013-04-27 18:20:55