我有这样的代码:
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);
}
接口(interface)在哪里:
public interface Processor {
public ArrayList<String> process(ArrayList<CustomObject> input);
}
似乎代码不是那么干净。我觉得我需要某种工厂模式和 builder 模式的结合。
我在这里做错了什么或者我该如何改进?
最佳答案
您可以将处理器接口(interface)重构为如下形式:
public interface Processor {
List<String> process(List<?> input);
}
这将允许它处理任何类型元素的列表并返回字符串列表。通常建议返回一个接口(interface)而不是特定的类,特别是如果您不使用该类可能具有的任何自定义方法。
下面是一个实现类的示例:
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 接口(interface)的类的新实例。我将解释其中的每一行:
final Constructor<? extends T> constructor = processorClass.getConstructor(paramsClass);
processorClass 参数表示我们希望创建的对象的类。我们使用它来检索具有与 paramsClass 数组中的元素相同的参数类型(和顺序)的类的构造函数(使用 Boxed Primitives 而不是 primites。
final Processor processor = constructor.newInstance(params);
我们使用 params vararg 创建所需类的新实例。参数的数量和类型必须与上述构造函数所期望的相同,否则 newInstance
调用将失败。
在此之后,我们只需将新创建的参数放入 map 中即可。
根据您希望执行的操作,可能需要同步 registerProcessor 和 getProcessor 方法。如果您确定只能通过您的代码注册处理器,您可能希望将 registerParameters 包设为私有(private)或将其设为静态初始化 block 。
这是注册调用的样子:
registerProcessor(Type.X, ProcessorImpl1.class, new Class[]{Integer.class}, 1);
registerProcessor(Type.Y, ProcessorImpl2.class, new Class[]{Integer.class, Integer.class}, 1, 3);
关于java - 工厂模式和 builder 模式的结合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38370653/