我有这样的代码:
public class ProcessorBuilder {
enum Type {
X,
Y,
}
private static HashMap<Type, Processor> processors = new HashMap<>();
public static void buildProcessors(int arg1, String arg2, CustomObject arg3) {
processors.put(Type.X, new ProcessorImpl1(arg1, arg2));
processors.put(Type.Y, new ProcessorImpl2(arg3));
}
public Processor getProcessor(Type type) {
return processors.get(type);
}
我有界面:
public interface Processor {
public ArrayList<String> process(ArrayList<CustomObject> input);
}
似乎代码不干净。我觉得我需要一些工厂和建筑师模式的结合 我在这里做错了什么,或者我该如何改进呢?
答案 0 :(得分:1)
您可以将Processor接口重构为以下内容:
public interface Processor {
List<String> process(List<?> input);
}
这将允许它处理任何类型元素的列表并返回字符串列表。通常建议返回一个接口而不是一个特定的类,特别是如果你不使用该类可能有的任何自定义方法。
以下是实现类的外观示例:
public class ProcessorImpl1 implements Processor {
public ProcessorImpl1(Integer arg1) {
}
@Override
public List<String> process(List<?> input) {
return Collections.emptyList();
}
}
构建器类可能如下所示:
public class ProcessorBuilder {
enum Type {
X,
Y,
}
private static final Map<Type, Processor> processors = new EnumMap<>(Type.class);
public static <T extends Processor> void registerProcessor(Type type, Class<? extends T> processorClass,
Class[] paramsClass, Object... params)
throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
final Constructor<? extends T> constructor = processorClass.getConstructor(paramsClass);
final Processor processor = constructor.newInstance(params);
processors.put(type, processor);
}
public static Processor getProcessor(Type type) {
return processors.get(type);
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
registerProcessor(Type.X, ProcessorImpl1.class, new Class[]{Integer.class}, 1);
registerProcessor(Type.Y, ProcessorImpl2.class, new Class[]{Integer.class, Integer.class}, 1, 3);
Processor p1 = getProcessor(Type.X);
p1.process(null);
Processor p2 = getProcessor(Type.Y);
p2.process(null);
}
}
我已经更新了处理器映射以使用EnumMap,因为这种映射比HashMap具有更好的性能,因为键是枚举值。如果使用枚举作为键(在EnumMap中)或值(在EnumSet中),则应始终使用EnumMap或EnumSet。
registerProcessor
方法用于构造使用反射实现Processor接口的类的新实例。我将从中解释每一行:
final Constructor<? extends T> constructor = processorClass.getConstructor(paramsClass);
processorClass参数指示我们要创建的对象的类。我们使用它来检索类的构造函数,该构造函数与paramsClass数组中的元素具有相同的参数类型(和顺序)(使用Boxed Primitives而不是primites。
final Processor processor = constructor.newInstance(params);
我们使用params vararg创建所需类的新实例。参数的数量和类型必须与上述构造函数所期望的相同,否则newInstance
调用将失败。
在此之后,我们只是将新创建的参数放在地图中。
根据您的要求,可能需要同步registerProcessor和getProcessor方法。如果您确定只从您的代码注册处理器,您可能希望将registerParameters包设为私有或使其成为静态初始化块。
以下是注册电话的外观:
registerProcessor(Type.X, ProcessorImpl1.class, new Class[]{Integer.class}, 1);
registerProcessor(Type.Y, ProcessorImpl2.class, new Class[]{Integer.class, Integer.class}, 1, 3);