Reputation: 1168
I am trying to implement Template method pattern, but I need a slight variation that I don't think is best practice. I have the following structure of classes
abstract class AbsClass {
public void algorithm(){
step1();
step2();
}
private void step1() {
//implementation
}
protected abstract void step2();
}
class A extends AbsClass {
protected void step2() {
// With implementation
}
}
class B extends AbsClass {
protected void step2() {
// No implementation needed
}
}
In the real case I have like 4 classes, and one of them doesn't need to have implementation for the second step. I don't think to leave the method empty would be good practice. I was thinking to put a comment(saying there is no need for implementation) in it, but I don't this would be the right solution. Is there another approach I am not seeing?
Upvotes: 0
Views: 1541
Reputation: 5336
We should not Force a design pattern. Here if we prefer Composition over inheritance then its better.
The code present in the question we have a method defined in a class but actually method has no behavior. Forcing a method in a class where it should not belomg to is not a good idea.
Below is one such possible implementation where you would not force a method to a class if it does not belong to it. Below is based on Strategy patter, but still I would say follow design principles and let the pattern itself suit your problem and do not force pattern to fit your solution.
public class AlgorithmClass {
private Strategy strategy;
public void setStrategy(Strategy strategy){
this.strategy = strategy;
}
public void algorithm(){
step1();
step2();
}
private void step1() {
//implementation
}
private void step2(){
if(this.strategy != null){
this.strategy.execute();
}
}
}
public interface Strategy{
public void execute();
}
public class Strategy1 implements Strategy{
public void execute(){
//implement your one of the stategies for step 2
}
}
public class Strategy2 implements Strategy{
public void execute(){
//implement your another stategy for step 2
}
}
Upvotes: 5
Reputation: 5240
I agree with @Vinay Avasthi's answer but I want to reinforce it.
Hook methods are defined in the base class and are a default implementation. And these can be overridden - they don't have to.
From Template-Method-Pattern Wikipedia page:
Template method's abstract class may also define hook methods that may be overridden by subclasses. These have a no-op implementation in the abstract class, but provide a "hook" on which to "hang" implementations.
What you should do is leave a comment in the method body like // empty method body
so that someone reading your code (and maybe your self) knows that this method has not been forgotten
There is a second way to implement the Template-Method-Pattern in Java. Since Java 8 it is possible to have default method implementations in an interface.
If your methods do not depend on state it could look like:
interface AbsClass {
default void algorithm(){
step1();
step2();
}
default void step1() {
// implementation or empty
}
default void step2() {
// empty body in default case
}
}
class B implements AbsClass { }
Upvotes: 3
Reputation: 952
I think it is absolutely fine. If the default behavior of step2 is to do nothing, then you can have an empty method in base class and override in child classes.
Upvotes: 2