#java #open-closed-principle
Вопрос:
У меня есть класс, и внутри него у меня есть метод, который отвечает за шаблон процесса, основанный на определенном условии
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
}
}
Каждую неделю на картинке появлялся новый шаблон, и я должен добавить его, если-иначе
Нет, мой вопрос заключается в том, что в соответствии с принципом SOLID класс принципа открытия и закрытия открыт для расширения и закрыт для модификации.
Итак, мне разрешено добавлять новую логику, основанную на новых условиях «если бы еще»?
Вот мой полный внешний вид кода
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();
Ответ №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);
}
}
Таким образом, в этом случае код для этого класса остается закрытым для изменения, но вы можете расширить то, что он делает (в этом случае добавьте больше кода процессора для разных идентификаторов).
Комментарии:
1. Я не понял кодовую часть @Jose Martinez
2. @Начинающий проверьте сейчас. Не хватало
public void
только этих методов. Таким образом, по сути, код какой-то другой фрагмент кода может вызватьaddProcessor
метод для добавления новых процессоров TempId.3. Но если я присмотрюсь, я верю
addProcessor
, что глубоко внутри работает то жеif-else
самое, что и при сохранении соответствующего процесса с идентификатором шаблона на КАРТЕ4. Привет, я обновил свой полный код @Jose Martinez
5. Принцип «открыто-закрыто» применяется именно к этому классу. Вам, как разработчику приложения, все еще нужен способ предоставить этому классу идентификатор TempId и метод обратного вызова…. через метод addProcessor. Это может быть сделано другим фрагментом кода, чья работа заключается в регистрации процессоров. Все утверждения «ЕСЛИ» исчезли. Тесты для каждой части кода становятся проще. Вы можете добавлять новые процессоры, не беспокоясь о нарушении функциональности класса. Каждая часть становится гипер сфокусированной на том, что ей нужно делать… и вам нужно только кормить ее новыми процессорами.