В моем приложении несколько различных отчетов могут быть сгенерированы (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()
Я хотел получить мнение других при использовании этого подхода. Что Вы думаете об этом? Вы предпочли бы какой-либо другой подход, и если так, почему?
Спасибо
Я думаю, что оба подхода подходят, но если вы не хотите знать, какой тип отчета вы создаете, я считаю, что подход enum является лучшим. Примерно так:
public class Person {
private String name;
private ReportType myPreferedReportType;
public ReportType getMyPreferedReportType(){
return this.myPreferedReportType;
}
//other getters & setters...
}
предположим, что вы сохраняете экземпляр Person в базе данных и извлекаете его позже - если вы используете полиморфизм, вам вообще не понадобится никакой переключатель. Единственное, что вам нужно сделать, это вызвать метод 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();
Итак, если вы полагаетесь на полиморфизм, вам не нужно будет просить фабрику явно предоставить вам CVS / HTML / PDF, оставив эту работу самому Enum. Но, конечно, есть ситуации, в которых вам может понадобиться использовать ту или иную, хотя я обычно использую подход enum регулярно.
Какое преимущество вы получаете, используя Enum, например, создание отчета? Если бы у вас был фабричный метод, вы бы создали бы экземпляр CSVReport (скажем), как ниже:
Report csvReport = ReportFactory.createCSVReport();
, который, я думаю, передает намерение лучше, чем у enum. Насколько я понимаю, перечисления представляют собой фиксированный набор констант, и используя его в качестве завода, например, создания экземпляра (хотя работает), кажется, мне неправильно распространяется на намерение перечисления.
Джошуа Блох (признанный эксперт Java) фактически рекомендует этот подход в своей книге Effectife Java 2-й издание на стр. 17: Обеспечить собственность Singleton с частным конструктор или тип enum.
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.