我在我的应用中为不同的“数据点”创建了一组接口。我希望能够以相当模块化的方式添加或删除“数据点”,并且只加载用户需要的那些。目前我只有一个列表中的所有这些,我通过ID访问我需要的列表。当我添加DataPointMethods接口的实现时,我想用自我更新的东西替换它,并且这不需要我实例化我的所有类,无论我是否需要它们。现在这不是一个大问题,但考虑到可扩展性,我知道它会是。
当前代码:
private void setupMethodsList() {
dataPointMethodsList = new ArrayList<DataPointMethods>();
dataPointMethodsList.add(WorkoutMethods.getInstance());
dataPointMethodsList.add(SleepMethods.getInstance());
dataPointMethodsList.add(WalkingMethods.getInstance());
dataPointMethodsList.add(FoodMethods.getInstance());
dataPointMethodsList.add(WeightMethods.getInstance());
dataPointMethodsList.add(WaterMethods.getInstance());
}
我可以制作一个如下所示的开关语句:
public DataPointMethods getDataPointMethod(int dataPointID){
DataPointMethods dataPointMethods;
switch (dataPointID) {
case 0:
dataPointMethods = FoodMethods.getInstance();
break;
case 1:
dataPointMethods = WorkoutMethods.getInstance();
break;
// TODO: add more cases each time I add a DataPoint...
default:
dataPointMethods = WorkoutMethods.getInstance();
Log.w(TAG, "invalid DataPointID passed");
break;
// How do I just make the method just stop if the ID is wrong though? If default runs it is 100% definitely an error...
}
return dataPointMethods;
}
虽然这可能是更好的表现,但维持起来却很痛苦。
有没有更理想的解决方案?到目前为止,我发现的唯一解决方案涉及实例化一切,这违背了目的......
答案 0 :(得分:0)
如果您需要低维护解决方案,可以使用ClassPathScanningCandidateComponentProvider
扫描类路径以获取实现接口的类的名称。然后你可以使用反射从那里开始。
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AssignableTypeFilter(DataPointMethods.class));
for (BeanDefinition bd : scanner.findCandidateComponents("basepackage")) {
Class<?> clazz = Class.forName(bd.getBeanClassName());
DataPointMethodsmethod = (DataPointMethods)clazz.getMethod("getInstance").invoke(null);
}