java - 工厂模式 - 字符串还是枚举?

标签 java design-patterns factory-pattern

从设计的角度来看,我一直在想,将枚举作为参数传递给工厂类是否比字符串更好?

我们以下面的代码为例:

class SomeFactory{

   public SomeObject getObject(String objectType){

      switch(objectType){

         case "TYPEA":
            return new SomeObjectA();

         case "TYPEB":
            return new SomeObjectB();

         default:
            {handle the situation of missing / or misspelled request here}

      }
   }
}

现在,我相信上面的实现很容易出现拼写错误,并且在 IDE 中,您必须导航到工厂类源代码并查看什么是可接受的输入...

我没有这样做,而是认为创建一个公共(public)内部枚举(例如称为 SOMEOBJECTS)并在那里存储所有可能的变体,将是一个更安全的选择。

实现看起来像这样:

class SomeFactory{

   // public inner enum that can be accessed through the factory.
   // preferably the name of the enum should be a all caps version of
   // the interface or super class that the subtypes (TYPEA, TYPEB..)
   // are implementing / extending.
   public enum SOMEOBJECTS{
      TYPEA,
      TYPEB,
      TYPE...
   }

   public SomeObject getObject(SOMEOBJECTS objectType){

      switch(objectType){

         case TYPEA:
            return new SomeObjectA();

         case TYPEB:
            return new SomeObjectB();

         default:
            // Putting a default as a good practice, even though the input now has been
            // restricted to whatever is inside the enum class.

      }
   }
}

我能想到的唯一警告是,为了访问枚举,您必须输入 SomeFactory.SOMEOBJECTS.TYPE..; .

也许我对此很着迷,但我相信每当更新工厂类时,枚举类中需要的这行额外的代码都会大有帮助。

我经常在书籍和在线文章中看到 Java 中使用字符串作为参数的工厂模式的第一个示例。

在实现工厂模式时,您同意这种方法吗?还是有我不知道的更好的方法?

最佳答案

使用枚举显然是最好的方法,因为它为您提供了每次调用都有有效参数的安全性。当然,这会带来维护开销,但您应该更愿意这样做,而不是因为某些无效字符串而导致程序崩溃。

<小时/>

我想提的另一件事是,使用工厂方法来创建不同类型的实例很奇怪。工厂类应该专用于一种类型。那么您就不必传递类型作为参数。您可以使用多个 getObject方法以及根据参数返回不同类型的方法。

<小时/>

仅供引用:您可以按类型传递类型

public static <T> T getObject(Class<T> type)
        throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
    return type.getConstructor().newInstance();
}


public static void main(String[] args) {
    try {
        Object o = getObject(Object.class);
    } catch (Exception e) {
        // I don't care.
    }
}

这显然很糟糕(或者更确切地说,如果使用错误可能),但也许这会给你关于这个主题的另一个视角。请注意,通用可以像<T extends SomeObject>一样使用,您可以比较类型..很多事情都是可能的。

关于java - 工厂模式 - 字符串还是枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60767750/

相关文章:

java - Netty:我应该创建新的 ChannelBuffer 来向每个客户端发送数据吗?

java - 何时将配置放在 file.properties 或 Jndi 中

java - 拥有一个以自身为场的对象是否合理?

ios - 改进冗余 if else 查询(也许使用设计模式?)并减少全局变量?

javascript - 优雅地将方法重新附加到 Web Worker 中的对象?

oop - 如何在不可变抽象基类的默认方法中实例化子类?

c# - 依赖注入(inject)刷新缓存

java - Jackson 如何将一个 Pojo 字段映射到 2 个(json)字段(相同的内容,不同的名称)

design-patterns - 工厂采用静态方法实现

java - 构造函数有很多元素。如何重构(工厂模式)