Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template Method pattern for static classes

I have a util class that perform some work. Obviously, it is closed for extension and all methods are static. For the sake of simplicity, the class looks like this:

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

The class has method doWork that performs a lot of calculations. By the way, method calls helper method help to obtain some result and rest of the code use the result returned by help method.

Now, in client code I want to reuse functionality of method doWork, but instead of calling help I want to call help2 method. The simplest solution just create method doWork2 with replacing help to help2.

It is very bad approach, because every change in doWork must be replicated in doWork2 either. This very similar to Template Method pattern, but due to fact that we don't have extension here, we can't apply it.

Best solution I came up with to add parameter to this method, but preserve all existing users of doWork:

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

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

What are better design solutions can be applied to solve this problem? Is there a way to achieve flexibility like Template Pattern has, but in application to util classes.

Thanks in advance.

like image 351
mishadoff Avatar asked Apr 26 '13 12:04

mishadoff


People also ask

Which classes is implementation of template method pattern?

All operations used by this template method are made abstract, so their implementation is deferred to subclasses. ConcreteClass implements all the operations required by the templateMethod that were defined as abstract in the parent class.

Which type of design pattern is the template method pattern?

Template Method is a behavioral design pattern. Template Method design pattern is used to create a method stub and deferring some of the steps of implementation to the subclasses.

What is Template Method pattern in C#?

Template Method is a behavioral design pattern that allows you to defines a skeleton of an algorithm in a base class and let subclasses override the steps without changing the overall algorithm's structure.

Can you alter the sequence of steps of any process with template pattern?

Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.


3 Answers

My suggestion is inspired in the Command Pattern, where Util class is a Invoker and each doWork-help pairs are encapsulated using the Worker interface.

The Worker Inteface could be some like

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

The Util Class

public final class Util {
    private Util() { }

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

}

The Concrete Worker (implementations of help and 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;
    }

}

Another Worker

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

}

And the Execution

Util.toWork(new ConcreteWorker());
Util.toWork(new ConcreteWorker2());
like image 147
Arnaldo Ignacio Gaspar Véjar Avatar answered Oct 27 '22 00:10

Arnaldo Ignacio Gaspar Véjar


You could create 2 static object Help1 & Help2 implementing Help interface wich have a help() method and change your doWorkWithParameter method like this:

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

It's closely related to your current solution. But I think it's a little more "Object Oriented".

like image 33
DeadlyJesus Avatar answered Oct 27 '22 01:10

DeadlyJesus


Not so long time ago I have made this:

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;

then we can call:

Constants.HELPER.doWork()

By switching HELPER constant values I can change behavior. or you can do:

Helper.OLD.doWork();
Helper.NEW.doWork();
like image 43
Mikhail Avatar answered Oct 27 '22 00:10

Mikhail