什么时候使用使用AbstractList
的适配器模式应该优于通过for-each从另一个列表构建结果列表?
给定以下 Java bean(为了可读性而跳过 getter/setter):
class ObjectError {
private String code;
}
class FieldError extends ObjectError {
private String field;
}
class ErrorMessage {
private String path;
private String messageKey;
}
以及Validator
类的以下方法:
public AllErrors validate(List<ObjectError> errors) {
AllErrors result= new AllErrors();
result.setErrors(convertErrors(errors));
return result;
}
List<ErrorMessage> convertErrors(List<ObjectError> errors) {
List<ErrorMessage> result = new ArrayList<>(errors.size());
for (ObjectError error : errors) {
ErrorMessage message = new ErrorMessage();
if (error instanceof FieldError) {
message.setMessageKey(((FieldError) error)).getPath();
}
message.setPath(error.getCode());
result.add(message);
}
return result;
}
我想重构convertErrors
.
首先,我们可以将 for 循环的内容提取到createErrorMessage
方法中,这样convertErrors
列表迭代,createErrorMessage
知道如何从ObjectError
实例创建单个ErrorMessage
:
List<ErrorMessage> convertErrors(List<ObjectError> errors) {
List<ErrorMessage> result = new ArrayList<>(errors.size());
for (ObjectError error : errors) {
result.add(createErrorMessage(error));
}
return result;
}
ErrorMessage createErrorMessage(ObjectError error) {
ErrorMessage message = new ErrorMessage();
if (error instanceof FieldError) {
message.setMessageKey(((FieldError) error)).getPath();
}
message.setPath(error.getCode());
return message;
}
现在有两个选项:
保持现状
当前代码可以从上到下读取,但Validator
类的组件不太可重用。
使用AbstractList
适配器
convertErrors
方法可以替换为列表适配器:
private static class ObjectErrorAdapter extends AbstractList<ErrorMessage> {
private List<ObjectError> objectErrors;
private ObjectErrorAdapter(List<ObjectError> objectErrors) {
this.objectErrors = objectErrors;
}
@Override public ErrorMessage get(int idx) {
return createErrorMessage(objectErrors.get(idx));
}
@Override public int size() {
return objectErrors.size();
}
ErrorMessage createErrorMessage(ObjectError error) {
ErrorMessage message = new ErrorMessage();
if (error instanceof FieldError) {
message.setMessageKey(((FieldError) error)).getPath();
}
message.setPath(error.getCode());
return message;
}
// Also hashCode() and equals() might be required for this class
}
public AllErrors validate(List<ObjectError> errors) {
AllErrors result= new AllErrors();
result.setErrors(new ObjectErrorAdapter(errors));
return result;
}
这个变体增加了很多代码和一些间接,但似乎增加了模块化、可重用性,从而增加了可测试性(?)。
哪种变体更可取,为什么?
使用AbstractList
的代码更复杂且更难理解。 由于您没有任何具体的理由来重构它(过早优化?),我会保持原样。