Java 工厂设计模式中避免if-else、switch-case的方法

Java 工厂设计模式中避免if-else、switch-case的方法,java,reflection,factory,checkstyle,cyclomatic-complexity,Java,Reflection,Factory,Checkstyle,Cyclomatic Complexity,我正在设计一个验证模块。它有100个要验证的错误代码(即errcd_01、errcd_02、…、errcd_100)。在输入中,我从100以上得到一个特定的错误代码(即errcd_01)。 模块应该对该特定错误代码执行验证 我使用的是工厂模式 /* Interface */ public interface validateErrCd { void check_errcd(); } /* Concrete classes implementing the same interface *

我正在设计一个验证模块。它有100个要验证的错误代码(即errcd_01、errcd_02、…、errcd_100)。在输入中,我从100以上得到一个特定的错误代码(即errcd_01)。 模块应该对该特定错误代码执行验证

我使用的是工厂模式

/* Interface */
public interface validateErrCd {
   void check_errcd();
}

/* Concrete classes implementing the same interface */
public class validateErrCd_01 implements validateErrCd {

   @Override
   public void check_errcd() {
      //business logic related to errcd_01
   }
}

public class validateErrCd_02 implements validateErrCd {

   @Override
   public void check_errcd() {
      //business logic related to errcd_02
   }
}
.
.
.
public class validateErrCd_100 implements validateErrCd {

   @Override
   public void check_errcd() {
      //business logic related to errcd_100
   }
}

/* Factory */
public class ErrorValidationFactory {
    
   //use check_errcd method to get object of type shape 
   public validateErrCd getValidation(String errorCode){
      if(errorCode == null){
         return null;
      }     
      if(errorCode.equalsIgnoreCase("errcd_01")){
         return new validateErrCd_01();
         
      } else if(errorCode.equalsIgnoreCase("errcd_02")){
         return new validateErrCd_02();
         
      } ..
       .......
      else if(errorCode.equalsIgnoreCase("errcd_100")){
         return new validateErrCd_100();
      }
      else {
           return null;
      }
   }
}

/* I am using the Factory to get object of concrete class by passing an specific error code to be validated (i.e. "errcd_01"). */
public class FactoryPatternDemo {

   public static void main(String[] args) {
      ErrorValidationFactory errorFactory = new ErrorValidationFactory();

      //get an object of validateErrCd_01 and call its check_errcd method.
      validateErrCd errcd01 = errorFactory.getValidation("errcd_01");

      //call check_errcd method of validateErrCd_01
      errcd01.check_errcd();
   }
} 
现在,由于工厂类ErrorValidationFactory中存在多个if/else,我在执行mvn clean安装时遇到了几个CI/CD错误。 e、 g.[MethodLength]-检查样式,规则:CyclomaticComplexity-PMD

那么,有没有一种方法可以替代工厂内部的if/else、switch case决策,而不触发Java中的上述CI/CD错误


注意:如果可能,我希望避免反射

您可以使用
地图

公共类ErrorValidationFactory{
私有映射创建者=新HashMap();
公共ErrorValidationFactory(){
creators.put(“errcd_100”,validateErrCd_100::new);
//其他人也一样
}
//使用check_errcd方法获取shape类型的对象
公共ValidateRCD getValidation(字符串错误代码){
if(errorCode==null){
返回null;
}
返回creators.getOrDefault(错误代码,()->null);
}
}
Supplier
是一个功能接口,包含返回对象的方法
SomeClass::new
()->new SomeClass()
表示将使用该类的构造函数进行此操作

这允许以后创建实例

如果只想创建一次
映射
,可以将其设置为
静态
,并将其填充到静态初始值设定项中


但是,如果您确实想动态获取构造函数,则需要使用反射。

您可以使用
映射

公共类ErrorValidationFactory{
私有映射创建者=新HashMap();
公共ErrorValidationFactory(){
creators.put(“errcd_100”,validateErrCd_100::new);
//其他人也一样
}
//使用check_errcd方法获取shape类型的对象
公共ValidateRCD getValidation(字符串错误代码){
if(errorCode==null){
返回null;
}
返回creators.getOrDefault(错误代码,()->null);
}
}
Supplier
是一个功能接口,包含返回对象的方法
SomeClass::new
()->new SomeClass()
表示将使用该类的构造函数进行此操作

这允许以后创建实例

如果只想创建一次
映射
,可以将其设置为
静态
,并将其填充到静态初始值设定项中


但是,如果您真的想动态获取构造函数,则需要使用反射。

创建一个
映射
,并用
validators.put(“errcd_100”,new validateErrCd_100())
等条目填充它。然后
.get()
用代码返回您的验证器。@VLAZ,这是行不通的,因为使用同一个键的两个调用将返回相同的实例,这可能不是OP所需要的,从它们所显示的代码判断(除非,也就是说,您在
getValidation
)@FedericoklezCulloca内创建映射,那么它只是一个带有
验证器的
映射(字符串,供应商)
,validateErrCd_100::new)
对吗?@VLAZ yep,这就是dan1st回答(现在)所说的:)创建一个
映射图
,并用类似
验证器的条目填充它。put(“errcd_100”,new validateErrCd_100())
然后
.get()
通过代码返回验证器。@VLAZ,这是行不通的,因为使用同一个键的两个调用将返回相同的实例,这可能不是OP所需要的,从它们所显示的代码判断(除非,也就是说,您在
getValidation
)@FedericoklezCulloca内创建映射,那么它只是一个带有
验证器的
映射(字符串,供应商)
,validateErrCd_100::new)
对吗?@VLAZ yep,这是dan1st的答案(现在)说的:)由于原始代码使用了
equalsIgnoreCase
,因此等效的解决方案将使用
新树映射(String.CASE不区分大小写顺序)
而不是
new HashMap()
。尽管如此,不区分大小写的匹配在这里是否有意义仍有争议。您还可以将查找简化为
returncreators.getOrDefault(errorCode,()->null.get()谢谢@dan1st它成功地避免了规则:CyclomaticComplexity-PMD。但是,因为我仍然需要在
creators.put(“errcd_100”,validateErrCd_100::new)中为每个errcd添加条目,它仍然给出[MethodLength]-checkstyle失败。如果某个列表中存在所有errcd(即,在本例中为1到100),是否有一种方法可以通过循环创建它?@Holger,我们目前可以忽略这种情况下的大小写敏感度。@Data\u Geek看起来您的具体类只存在于实现
validateErrCd
接口方法和不携带(可变)状态的情况下。那么,您真的需要在
getValidation
中实例化它们吗?或者每种类型使用一个单例是可行的吗?如果是这种情况,只需将它们全部实现为
enum
类型,您就可以免费枚举它们(甚至可以按名称查找它们)。由于原始代码使用
equalsIgnoreCase
,因此等效的解决方案将使用
新树映射(String.case\u INSENSITIVE\u ORDER)
而不是
新的HashMap()
。尽管如此,不区分大小写的匹配在这里是否有意义仍有争议。您还可以将查找简化为
returncreators.getOrDefault(errorCode,()->null.get()谢谢@dan1st它成功地避免了规则:CyclomaticComplexity-PMD。但是,因为我仍然需要在
creators.put(“errcd_100”,validateErrCd_100::new)中为每个errcd添加条目,它仍然给出[MethodLength]-checkstyle失败。我们有办法创造它吗