静态类的模板方法模式

问题描述:

我有一个执行一些工作的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

我的建议是在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

你可以创建2个静态对象Help1 & Help2实现Help接口至极有帮助()方法,改变你的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常数值我可以改变的行为。或者你可以这样做:

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

谢谢,好戏。 – mishadoff 2013-04-26 13:16:47

+0

这是有效的Java书 - “项目34:效法扩展枚举与接口” – Mikhail 2013-04-27 18:20:55