java - 工厂模式和 builder 模式的结合?

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

接口(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/

相关文章:

java - 单击通知时启动 Activity

c++ - 如何在关键字 this 上调用重载的 () 运算符?

javascript - 在揭示模块模式中使用自执行匿名函数

java - 构建该对象的更好模式?

java - 在 JNI 调用后尝试过快地访问数组时出现段错误

java - 如何在 Maven 中显示消息

java - 如何在 Java 中实现抽象静态方法?

oop - 在实体被认为臃肿之前,我们可以合理地将多少方法放入实体中?

c# - Decorator模式中抽象Decorator类的使用

java - Android TCP 客户端。服务器仅在进程停止后接收消息