1

I have a class and inside that, I have a method which is responsible for process Template based on the certain condition

public doProcessing(@RequestParam("tempId") int TempId){
if(tempId == 1){
//some logic
}
elseIf(tempId == 2){
// another type of logic
}
elseIf(tempId == 3){
// some more complex type of logic
}
}

Every week a new Template came into the picture and I have to add this if-else

No, my question is According to the SOLID principle open and close principle class is open for extension and closed for modification.

So I am allowed to add new logic based on new if-else conditions?

Here is my complete look like code

public interface TemplateClassification {
    QuesObj processTemplate();
}


public class Template1 implements  TemplateClassification{
    
    @Override
    public QuesObj processTemplate() {
        return new QuesObj("Hi I am header 1","Hi I am footer 1");
    }
}


public class Template2 implements  TemplateClassification{
    @Override
    public QuesObj processTemplate() {
        return new QuesObj("Hi I am header 2","Hi I am footer 2");
    }
}

public class TemplateInfo {

    private TemplateClassification templateClassification;

    public TemplateClassification getTemplateClassification() {
        return templateClassification;
    }

    public void setTemplateClassification(TemplateClassification templateClassification) {
        this.templateClassification = templateClassification;
    }
}

public class TemplateProduct {
    public QuesObj calculateTemplate(TemplateInfo templateInfo){
        QuesObj ques = templateInfo.getTemplateClassification().processTemplate();
        return ques;
    }
}

@RestController
class Pg {

    @Autowired
    TemplateInfo templateInfo;

    @Autowired
    TemplateProduct templateProduct;

    public doProcessing(@RequestParam("tempId") int TempId){
        QuesObj ques = null;
        if(tempId == 1){
          Template1 temp = new Template1(); 
          ques = templateProduct.calculateTemplate(templateInfo);
        }
        elseIf(tempId == 2){
          Template2 temp = new Template2(); 
          ques = templateProduct.calculateTemplate(templateInfo);
        }
        elseIf(tempId == 3){
        // coming soon
        }
    }
}

Should I use Class.forName and then create the new instance for it will it be a good practice?

Class c = Class.forName("ocp."+state);

TemplateClassification ref = (TemplateClassification)c.newInstance();
Beginner
  • 145
  • 7

1 Answers1

1

This is a great example to show the open-closed principle in action. Constantly adding new IF statements I think breaks the closed part of this principle. Mainly because you are altering code that belongs to that class.

One way to make it better abide by the open-close principle is to use the call-back pattern. For example the class can take an integer and a callback, and add it to its list of processors. Below is some sample code.

public void addProcessor(Integer tempId, Consumer<Integer> processor)
    procesorMap.put(tempId, processor);
}

public void doProcessing(@RequestParam("tempId") int TempId){
    if(processorMap.contains(TempId) {
        processorMap.get(TempId).accept(TempId);
    }
}

So in this case, the code for this class stays closed for modification, but you can extend what it does (in this case add more processor code for different IDs).

Jose Martinez
  • 11,452
  • 7
  • 53
  • 68
  • I didn't understand the code part @Jose Martinez – Beginner Aug 12 '21 at 17:50
  • @Beginner check now. Was missing the `public void` to those methods. So essentially code some other piece of code can call the `addProcessor` method to add new TempId processors. – Jose Martinez Aug 12 '21 at 18:03
  • But if I look closely I believe ```addProcessor``` is deep inside working same as ```if-else``` as we are saving the corresponding process with template id in MAP – Beginner Aug 12 '21 at 18:09
  • Hi, I have updated my complete code @Jose Martinez – Beginner Aug 12 '21 at 19:18
  • The open-close principle is being applied to this particular class. You as a developer of the application still needs a way to supply this class with the TempId and the callback method.... via the addProcessor method. That can be done by another piece of code whose job it is to register processors. All the IF statements are gone. The tests for each part of the code become easier. You can add new processors without having to worry about breaking the class' functionality. Each part becomes hyper focussed on just what it needs to do... and you need to only feed it new processors. – Jose Martinez Aug 14 '21 at 01:52