这是基本的OO。您需要从您用来实现的机制(数据库查询或 Web 服务调用)中抽象出您试图实现的目标 - 加载数据。
这样的设计通常会涉及一个接口,该接口定义了可以做什么的契约,然后是多个实现类,这些类根据它们的实现来实现。
例如,您最终会得到一个类似于以下内容的界面:
public interface DataLoader
{
public Collection<Data> loadData() throws DataLoaderException;
}
然后,您将拥有诸如JdbcDataLoader
,WebServiceDataLoader
等的实现。在您的情况下,您将需要另一种类型的实现,该实现给定一个或多个实例DataLoader
, 运行每个累加汇总结果。这个实现看起来像:
public class AggregatingDataLoader implements DataLoader
{
private Collection<DataLoader> dataLoaders;
private ExecutorService executorService;
public AggregatingDataLoader(ExecutorService executorService, Collection<DataLoader> dataLoaders)
{
this.executorService = executorService;
this.dataLoaders = dataLoaders;
}
public Collection<Data> loadData() throws DataLoaderException
{
Collection<DataLoaderCallable>> dataLoaderCallables = new ArrayList<DataLoaderCallable>>();
for (DataLoader dataLoader : dataLoaders)
{
dataLoaderCallables.add(new DataLoaderCallable(dataLoader));
}
List<Future<Collection<Data>>> futures = executorService.invokeAll(dataLoaderCallables);
Collection<Data> data = new ArrayList<Data>();
for (Future<Collection<Data>> future : futures)
{
add.addAll(future.get());
}
return data;
}
private class DataLoaderCallable implements Callable<Collection<Data>>
{
private DataLoader dataLoader;
public DataLoaderCallable(DataLoader dataLoader)
{
this.dataLoader = dataLoader;
}
public Collection<Data> call()
{
return dataLoader.load();
}
}
}
您需要为此添加一些超时和异常处理逻辑,但您明白了要点。
另一个重要的事情是您的调用代码应该只使用DataLoader
接口,以便您可以在测试期间交换不同的实现或使用模拟。