Beginner
Beginner

Reputation: 145

How to achieve Open closed principle in correct way?

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

Upvotes: 1

Views: 467

Answers (1)

Jose Martinez
Jose Martinez

Reputation: 11992

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

Upvotes: 1

Related Questions