Template method template for static classes

I have a util class that does some work. Obviously, it is closed for extension, and all methods are static. For simplicity, the class is as follows:

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 a doWork method that does a lot of calculations. By the way, the method calls the helper help method to get some result, and the rest of the code uses the result returned by the help method.

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

This is a very bad approach, because every change in doWork must be replicated in doWork2 . This is very similar to the Template Method template, but due to the fact that we do not have an extension here, we cannot use it.

The best solution I've come up with is to add a parameter to this method, but keep all existing doWork users:

 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 the best design solutions to solve this problem? Is there a way to achieve flexibility, for example, the Template Pattern has, but in the application for using classes.

Thanks in advance.

+6
source share
3 answers

My suggestion is inspired by the Command Pattern , where the Util class is Invoker, and each doWork-help pair is encapsulated using the Worker interface.

The working integral may look like

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

Util class

 public final class Util { private Util() { } public static void toWork(Worker worker){ worker.doWork(); } } 

Concrete worker (help and doWork implementation)

 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 execution

 Util.toWork(new ConcreteWorker()); Util.toWork(new ConcreteWorker2()); 
+5
source

You can create 2 static Help1 and Help2 that implement the Help interface, which has a help () method, and change your doWorkWithParameter method as follows:

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

It is closely related to your current decision. But I think this is a little more "Object Oriented."

+1
source

Not so long ago I did 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 name:

 Constants.HELPER.doWork() 

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

 Helper.OLD.doWork(); Helper.NEW.doWork(); 
+1
source

Source: https://habr.com/ru/post/943710/


All Articles