工厂和建筑师模式的结合?

时间:2016-07-14 09:34:55

标签: java oop design-patterns

我有这样的代码:

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);  
}

似乎代码不干净。我觉得我需要一些工厂和建筑师模式的结合 我在这里做错了什么,或者我该如何改进呢?

1 个答案:

答案 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);