[英]better approach to set fields for java bean
I want to set different field value everytime when I create a bean.我想每次创建 bean 时都设置不同的字段值。 But there are a lot of field to set.
但是有很多字段要设置。 I can set those by using constructor.
我可以使用构造函数来设置它们。 But if there is a better approach to do this?
但是如果有更好的方法来做到这一点呢?
The code just like below, there are five errors, and every time using the bean need to specify different five errors.代码如下,有五个错误,每次使用bean需要指定不同的五个错误。 I am specifing those errors by constructor, this can work.
我正在通过构造函数指定这些错误,这可以工作。 But I know this is not an elegant way.
但我知道这不是一种优雅的方式。
Can I do this in better way ?我能以更好的方式做到这一点吗?
public class WildcardNumberValidator extends BaseValidator<String> {
private ErrorInfo wildcardCountError;
private ErrorInfo regionWildcardError;
private ErrorInfo festivalWildcardError;
private ErrorInfo backwardWildcardError;
private ErrorInfo keyWildcardError;
private ErrorInfo totalWildcardError;
public WildcardNumberValidator(ErrorInfo wildcardCountError,
ErrorInfo regionWildcardError,
ErrorInfo festivalWildcardError,
ErrorInfo backwardWildcardError,
ErrorInfo keyWildcardError,
ErrorInfo totalWildcardError) {
this.wildcardCountError = wildcardCountError;
this.regionWildcardError = regionWildcardError;
this.festivalWildcardError = festivalWildcardError;
this.backwardWildcardError = backwardWildcardError;
this.keyWildcardError = keyWildcardError;
this.totalWildcardError = totalWildcardError;
}
@Override
public boolean validate(ValidatorContext context, String str) {
int totalNum = regionNum + festivalNum + keyNum + regionNum;
if (maxRegionNum != null && regionNum > maxRegionNum) {
context.addError(regionWildcardError);
return false;
}
if (maxFestivalNum != null && festivalNum > maxFestivalNum) {
context.addError(festivalWildcardError);
return false;
}
if (maxBackwardNum != null && backwardNum > maxBackwardNum) {
context.addError(backwardWildcardError);
return false;
}
if (maxKeyNum != null && keyNum > maxKeyNum) {
context.addError(keyWildcardError);
return false;
}
if (maxTotalNum != null && totalNum > maxTotalNum) {
context.addError(totalWildcardError);
return false;
}
return true;
}
}
You can try accepting various ErrorInfo
as collection.您可以尝试接受各种
ErrorInfo
作为集合。 Let's say Map
of errorInfoType
and actual ErrorInfo
object.假设
errorInfoType
和实际ErrorInfo
对象的Map
。 errorInfoType
can be of Enum
type ie Map<ErrorInfoEnum, ErrorInfo> errorInfoMap
. errorInfoType
可以是Enum
类型,即Map<ErrorInfoEnum, ErrorInfo> errorInfoMap
。
You can modify your code something like below and try:您可以像下面那样修改您的代码并尝试:
public class WildcardNumberValidator extends BaseValidator<String> {
private Map<ErrorInfoEnum, ErrorInfo> errorInfoMap = new HashMap<>();
public WildcardNumberValidator(Map<ErrorInfoEnum, ErrorInfo> errorInfoMap) {
this.errorInfoMap = errorInfoMap;
}
@Override
public boolean validate(ValidatorContext context, String str) {
int totalNum = regionNum + festivalNum + keyNum + regionNum;
if (maxRegionNum != null && regionNum > maxRegionNum) {
context.addError(errorInfoMap.get(ErrorInfoEnum.REGION_WILD_CARD_ERROR));
return false;
}
if (maxFestivalNum != null && festivalNum > maxFestivalNum) {
context.addError(errorInfoMap.get(ErrorInfoEnum.FESTIVAL_WILD_CARD_ERROR));
return false;
}
if (maxBackwardNum != null && backwardNum > maxBackwardNum) {
context.addError(errorInfoMap.get(ErrorInfoEnum.BACKWARD_WILD_CARD_ERROR));
return false;
}
if (maxKeyNum != null && keyNum > maxKeyNum) {
context.addError(errorInfoMap.get(ErrorInfoEnum.KEY_WILD_CARD_ERROR));
return false;
}
if (maxTotalNum != null && totalNum > maxTotalNum) {
context.addError(errorInfoMap.get(ErrorInfoEnum.TOTAL_WILD_CARD_ERROR));
return false;
}
return true;
}
}
ErrorInfoEnum
: ErrorInfoEnum
:
enum ErrorInfoEnum {
WILD_CARD_COUNT_ERROR,
REGION_WILD_CARD_ERROR,
FESTIVAL_WILD_CARD_ERROR,
BACKWARD_WILD_CARD_ERROR,
KEY_WILD_CARD_ERROR,
TOTAL_WILD_CARD_ERROR
}
Better yet, if ErrorInfo
instances are immutable, you can make ErrorInfo
itself an enum
:更好的是,如果
ErrorInfo
实例是不可变的,您可以将ErrorInfo
本身设置为enum
:
public class WildcardNumberValidator extends BaseValidator<String> {
enum ErrorInfo {
COUNT_ERROR(1, "count ..."),
REGION_ERROR(2, "foo"),
FESTIVAL_ERROR(129, "bar"),
BACKWARD_ERROR(76, "fred"),
KEY_ERROR(99, "baz"),
TOTAL_ERROR(101, "xyzzy");
// whatever your ErrorInfo does
private int code;
private String message;
WildcardErrorInfo(int code, String message) {
this.code = code;
this.message = message;
}
}
// default constructor
public WildcardNumberValidator() {
}
@Override
public boolean validate(ValidatorContext context, String str) {
int totalNum = regionNum + festivalNum + keyNum + regionNum;
if (maxRegionNum != null && regionNum > maxRegionNum) {
context.addError(ErrorInfo.REGION_ERROR);
return false;
}
...
return true;
}
}
You can try to inverse the responsibility, instead of WildcardNumberValidator trying to validate your input, you can make ErrorInfo do that.您可以尝试反转责任,而不是 WildcardNumberValidator 尝试验证您的输入,您可以让 ErrorInfo 这样做。
public class WildcardNumberValidator extends BaseValidator<String> {
private List<ErrorInfo> errors;
public WildcardNumberValidator(List<ErrorInfo> errors) {
this.errors=errors;
}
@Override
public boolean validate(ValidatorContext context, String str) {
List<ErrorInfo> faildChecks= errors.stream()
.filter(error->error.check(str))
.collect(Collectors.toList());
if(faildChecks.empty()){
return true;
}
faildChecks.forEach(error->context.addError(error));
return false;
}
}
where ErrorInfo will like this:其中 ErrorInfo 会喜欢这个:
class ErrorInfo {
private Predicate<String> predicate;
void setPredicate(Predicate<String> predicate){
this.predicate=predicate;
}
boolean check(String input){
return predicate.test(input);
}
}
How to use:如何使用:
void test(){
//... do other stuff
int totalNum = regionNum + festivalNum + keyNum + regionNum;
ErrorInfo wildcardCountError= // init your ErrorInfo;
wildcardCountError.setPredicate(input-> maxRegionNum != null && regionNum > maxRegionNum)
// the same for other ErrorInfo,
WildcardNumberValidator validator = new WildcardNumberValidator(List.of(wildcardCountError,...other errors);
}
A couple of suggested ways to do this are to use static factory methods or builder pattern.一些建议的方法是使用静态工厂方法或构建器模式。
Factory method can give you freedom to name your methods.工厂方法可以让你自由地命名你的方法。 Builder can help you build objects in steps.
Builder 可以帮助您逐步构建对象。 There are other advantages as well.
还有其他优点。 This is one of the first guidelines suggested in the Effective Java book.
这是 Effective Java 一书中建议的第一个准则之一。 I will recommended the book highly.
我会高度推荐这本书。 Table of Contents
目录
A library you can take a look at is lombok .您可以查看的一个库是lombok 。 You can declare a class as
data
class/ builder
, etc and it will save of even writing those boilerplate lines of code.您可以将一个类声明为
data
类/ builder
等,它甚至可以节省编写那些样板代码行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.