问题 Enum工厂式的方法


在我的应用程序中,可以生成几个不同的报告(CSV,HTML等)。

我没有创建传统的工厂式方法模式,而是计划在枚举常量体中添加一个方法,该方法将创建并返回相应的报表对象。

public enum ReportType {
 CSV {
  @Override
  public Report create() {
   return new CSVReport();
  }
 },
 HTML {
  @Override
  public Report create() {
   return new HTMLReport();
  }
 };

 public abstract Report create();
}

使用指定的ReportType枚举常量,我可以通过执行如下语句轻松创建新报表:

ReportType.CSV.create()

我希望得到其他人对使用这种方法的看法。你觉得这怎么样?您是否更喜欢其他任何方法,如果是,为什么?

谢谢


1646
2018-01-29 16:39


起源



答案:


我认为这两种方法都可以,但如果你不想知道你正在生成哪种报告,那么我认为enum方法是最好的。像这样:

public class Person { 
    private String name;
    private ReportType myPreferedReportType;

    public ReportType getMyPreferedReportType(){
        return this.myPreferedReportType;
    }
    //other getters & setters...
}

假设您在数据库上持久化Person实例并在以后检索它 - 如果您使用polimorphism,则不需要任何切换。你唯一需要做的就是 调用create()方法。喜欢:

Person person = null; 
//... retrieve the person instance from database and generate a 
//report with his/her prefered report type...
Report report = person.getReportType.create();

因此,如果您依赖于polimorphism,您将无需要求工厂明确地为您提供CVS / HTML / PDF,将该工作留给Enum本身。但是,当然,有些情况下您可能需要使用其中一种,尽管我倾向于定期使用枚举方法。


4
2018-02-10 12:54





使用枚举作为报告创建的例子有什么好处?如果您有工厂方法,您将创建一个CSVReport实例(如下):

Report csvReport = ReportFactory.createCSVReport();


3
2018-01-29 17:28



有效点。 Java中的枚举通常以包含常量的方式使用,因为它们是类。我想我更喜欢给出Report类型的简单性,然后我可以选择在没有任何工厂的情况下创建它。这不一定需要工厂的额外代码。 - Steve
使用枚举,实际上是抽象工厂的重点是从请求创建的角度删除您决定实现细节的点。 (所以,如果你永远不会去除那些点,那么过早的间接就没有意义了。) - Tom Hawtin - tackline


答案:


我认为这两种方法都可以,但如果你不想知道你正在生成哪种报告,那么我认为enum方法是最好的。像这样:

public class Person { 
    private String name;
    private ReportType myPreferedReportType;

    public ReportType getMyPreferedReportType(){
        return this.myPreferedReportType;
    }
    //other getters & setters...
}

假设您在数据库上持久化Person实例并在以后检索它 - 如果您使用polimorphism,则不需要任何切换。你唯一需要做的就是 调用create()方法。喜欢:

Person person = null; 
//... retrieve the person instance from database and generate a 
//report with his/her prefered report type...
Report report = person.getReportType.create();

因此,如果您依赖于polimorphism,您将无需要求工厂明确地为您提供CVS / HTML / PDF,将该工作留给Enum本身。但是,当然,有些情况下您可能需要使用其中一种,尽管我倾向于定期使用枚举方法。


4
2018-02-10 12:54





使用枚举作为报告创建的例子有什么好处?如果您有工厂方法,您将创建一个CSVReport实例(如下):

Report csvReport = ReportFactory.createCSVReport();


3
2018-01-29 17:28



有效点。 Java中的枚举通常以包含常量的方式使用,因为它们是类。我想我更喜欢给出Report类型的简单性,然后我可以选择在没有任何工厂的情况下创建它。这不一定需要工厂的额外代码。 - Steve
使用枚举,实际上是抽象工厂的重点是从请求创建的角度删除您决定实现细节的点。 (所以,如果你永远不会去除那些点,那么过早的间接就没有意义了。) - Tom Hawtin - tackline


看着那(这 与访客模式的枚举。使用这种方法,您将能够动态地向枚举添加功能,而不必污染枚举本身。


2
2018-02-10 13:59





Joshua Bloch(公认的Java专家)实际上在第17页的Effective Java 2nd Edition一书中推荐了这种方法:使用私有来强制执行单例属性 构造函数或枚举类型。


1
2018-01-29 16:47



这与单身人士有关。 - Steve