静态类的模板方法模式

时间:2013-04-26 12:47:13

标签: java design-patterns template-method-pattern

我有一个执行某些工作的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。顺便说一句,方法调用helper方法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类时。

提前致谢。

3 个答案:

答案 0 :(得分:5)

我的建议受到Command Pattern的启发,其中Util类是一个Invoker,每个doWork-help对都是使用Worker接口封装的。

工人界面可能有点像

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

}

另一名工人

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());

答案 1 :(得分:1)

你可以创建2个静态对象Help1& Help2实现Help接口,它有一个help()方法,并像这样更改你的doWorkWithParameter方法:

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

这与您当前的解决方案密切相关。但我认为它更像是“面向对象”。

答案 2 :(得分: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();