Java 工厂设计模式中避免if-else、switch-case的方法
我正在设计一个验证模块。它有100个要验证的错误代码(即errcd_01、errcd_02、…、errcd_100)。在输入中,我从100以上得到一个特定的错误代码(即errcd_01)。 模块应该对该特定错误代码执行验证 我使用的是工厂模式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 *
/* 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失败。我们有办法创造它吗