什么时候应该使用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
知道如何创建单个ErrorMessage
ObjectError
个实例:
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
方法可以替换为List适配器:
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;
}
这种变体增加了许多代码和一些间接性,但似乎增加了模块性,可重用性和可测试性(?)。
哪种变体更可取,为什么?
答案 0 :(得分:0)
使用toString()
的代码更复杂,更难以理解。
既然你没有任何具体的理由来重构这个(过早的优化?),我会保持原样。