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.
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.
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.
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.
Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
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());
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With