【问题标题】:How to achieve Open closed principle in correct way?如何正确实现开闭原则?
【发布时间】:2021-10-16 01:56:24
【问题描述】:

我有一个类,里面有一个方法,负责根据特定条件处理模板

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
}
}

每周都会出现一个新模板,我必须添加这个 if-else

不,我的问题是根据SOLID原则开闭原则,类是对扩展开放,对修改关闭。

所以我可以根据新的 if-else 条件添加新逻辑吗?

这是我的完整代码

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
        }
    }
}

我应该使用Class.forName,然后为其创建新实例吗?

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

TemplateClassification ref = (TemplateClassification)c.newInstance();

【问题讨论】:

    标签: java open-closed-principle


    【解决方案1】:

    这是展示开闭原则的一个很好的例子。我认为不断添加新的 IF 语句会破坏该原则的封闭部分。主要是因为您正在更改属于该类的代码。

    使其更好地遵守开闭原则的一种方法是使用回调模式。例如,该类可以接受一个整数和一个回调,并将其添加到其处理器列表中。下面是一些示例代码。

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

    因此,在这种情况下,此类的代码保持关闭以进行修改,但您可以扩展它的功能(在这种情况下,为不同的 ID 添加更多处理器代码)。

    【讨论】:

    • 我不明白代码部分@Jose Martinez
    • @Beginner 现在检查。这些方法缺少public void。所以本质上代码一些其他的代码可以调用addProcessor方法来添加新的TempId处理器。
    • 但如果我仔细观察,我相信addProcessorif-else 的工作原理相同,因为我们正在MAP 中使用模板ID 保存相应的进程
    • 嗨,我已经更新了我的完整代码@Jose Martinez
    • 开闭原则被应用于这个特定的类。作为应用程序的开发人员,您仍然需要通过 addProcessor 方法为此类提供 TempId 和回调方法。这可以通过另一段用于注册处理器的代码来完成。所有的 IF 语句都消失了。代码的每个部分的测试变得更加容易。您可以添加新的处理器,而不必担心会破坏类的功能。每个部分都变得非常专注于它需要做的事情......你只需要为其提供新的处理器。
    猜你喜欢
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多