11

In my application, several different reports can be generated (CSV, HTML, etc).

Instead of creating a traditional factory-style method pattern, I was planning on adding a method to the body of enum constants that would create and return the appropriate report object.

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

 public abstract Report create();
}

With a specified ReportType enum constant, I could then easily create a new report by executing a statement like the following:

ReportType.CSV.create()

I wanted to get the opinion of others on using this approach. What do you think of this? Would you prefer any other approach, and if so, why?

Thanks

Vargen
  • 696
  • 2
  • 7
  • 20
Steve
  • 53,375
  • 33
  • 96
  • 141

4 Answers4

5

I think both approaches are ok, but if you don't want to know which kind of report you're generating then I believe that the enum approach is the best. Like so:

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

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

supose you persist a Person instance on a database and retrieve it later on - if you use polimorphism you won't need any switch wathsoever. The only thing you'll need to do is to call the create() method. Like:

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

So if you rely on polimorphism you won't need to ask a factory to get you the CVS/HTML/PDF explicitly, leaving that work to the Enum itself. But of course, there are situations that you may need to use one or another, although I tend to use the enum approach regularly.

Lucas de Oliveira
  • 1,642
  • 11
  • 16
3

What is the advantage you gain by using enum for instance of Report creation ? If you had factory-method you would have created an instance of CSVReport (say) like below:

Report csvReport = ReportFactory.createCSVReport();

which I think conveys the intent better than the enum. As I understand Enumerations represent a fixed set of constants, and using it as a factory for instance creation (though works) seems to me misuse of the intent of Enumeration.

sateesh
  • 27,947
  • 7
  • 36
  • 45
  • Valid point. Enum's in Java are often used in ways outside of just containing constants as they are classes. I guess I prefer the simplicity that given a Report type, I can then choose to create it without any factories. This would not necessarily require extra code for the factory. – Steve Jan 29 '10 at 17:41
  • 3
    The point of using enums, and indeed of abstract factories, is the point at which you decide on implementation details is removed from the point of requesting creation. (So, if you are never going to decouple those points, there is no point in premature indirection.) – Tom Hawtin - tackline Jan 29 '10 at 18:51
2

Look at the Enum with Visitor Pattern. With that approach you'll be able to dynamically add functionality to an enum without having to pollute the enum itself.

Community
  • 1
  • 1
mtpettyp
  • 5,533
  • 1
  • 33
  • 33
1

Joshua Bloch (recognized Java expert) actually recommends this approach in his book Effective Java 2nd Edition on page 17: Enforce the singleton property with a private constructor or an enum type.

Greg
  • 313
  • 1
  • 4