我有多个实现接口并返回对象的类。
public interface DataFetcher {
Data getData(Info info);
}
public class Data {
private String name;
private String value;
}
@Component
public class DataPointA implements DataFetcher {
@Override
public Data getData(Info info) {
//..Do some processing
return new Data("SomeName", valueComputed);
}
}
现在我有大约20个数据点,它们实现DataFetcher类并返回数据对象。
我将所有数据点自动连接到一个类,并根据某些条件使用某些数据点。
@Component
public class DataComputer {
@Autowired
private DataPointA dataPointA;
@Autowired
private DataPointB dataPointB;
.
.
.
public void computeData(String inputType, Info info) {
List<DataFetcher> dataFecthers;
switch(inputType) {
case "typeA" : dataFecthers = ImmutableList.of(dataPointA, dataPointB);
break;
.
.
.
case "typeD" : dataFecthers = ImmutableList.of(dataPointE, dataPointF, dataPointG);
break;
}
dataFetcher.forEach(dataPoint -> {
//Do some processing with dataPoint.getData(info)
})
}
}
可以看出,DataComputer类将具有依赖项的完整列表,这些依赖项可能变得难以管理。另外,基于输入类型要使用的数据点也是事先已知的,因此可以将其提取出来。这是我的尝试:
@Component
public class DataComputationPointDecider {
@Autowired
private DataPointA dataPointA;
@Autowired
private DataPointB dataPointB;
.
.
.
@Bean
public Map<String, List<DataFetcher>> getDataComputationPoints() {
return new ImmutableMap.Builder<String, List<DataFetcher>>()
.put("typeA", ImmutableList.of(dataPointA, dataPointB))
.put("typeD", ImmutableList.of(dataPointE, dataPointF, dataPointG))
.build();
}
}
然后我的DataComputer依赖关系减少了:
@Component
public class DataComputer {
@Autowired
private Map<String, List<DataFetcher>> dataComputationPoints;
public void computeData(String inputType, Info info) {
List<DataFetcher> dataFecthers = dataComputationPoints.get(inputType);
dataFetcher.forEach(dataPoint -> {
//Do some processing with dataPoint.getData(info)
})
}
}
有没有更好的方法来设计这个?
答案 0 :(得分:2)
我认为您的处理方法没有重大错误。但我建议再选择一个。
您可以使 <TextField
onChange={this.onChange}
className={classes.textField}
label={Multilanguage.Translate(this.props.label)}
autoFocus={true}
/>
onChange = (event) => {
if (event.target.value != null) {
this.setState({ serial: event.target.value });
}
}
决定或说出它可以处理的输入类型,而不是维护将inputType
与列表DataFetcher
映射的映射。
但这需要将DataFetcher
的界面更改为
DataFetcher
实现看起来像
public interface DataFetcher {
boolean canHandle(String inputType);
Data getData(Info info);
}
然后,您可以将所有@Component
public class DataPointA implements DataFetcher {
@Override
boolean canHandle(String inputType) {
return "typeA".equals(inputType);
}
@Override
public Data getData(Info info) {
//..Do some processing
return new Data("SomeName", valueComputed);
}
}
注入为一个列表(不必为每个列表添加一个DataFetcher
字段)并将其处理为
@Autowired
优势:
在当前方法中,如果添加新的@Autowired
List<DataFetcher> dataFetchers;
...
dataFetchers.stream()
.filter(dataFetcher -> dataFetcher.canHandle(inputType))
.forEach(dataFetcher.getData(info));
实现,则需要添加DataFetcher
字段/成员并修改(getDataComputationPoints)映射。但是,有了它,@AutoWired
可以处理的inputTypes本身就被指定了,因此您只需要为新的输入类型添加新的类即可。
参考
Autowire reference beans into list by type
更新:
缺点
在类内部指定了输入类型,这意味着您无法轻松找到给定输入类型的DataFetcher
(数据点)列表。
如果需要删除对inputType的支持,则再次需要访问每个实现(从DataFetchers
中删除该inputType)。在您的方法中,它只是删除一个地图条目。
答案 1 :(得分:0)
您是否考虑过使用Factory模式?这样,您可以根据某些条件为对象实例提交请求。