Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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".

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top