Метод enum factory -style
В моем приложении может быть создано несколько различных отчетов (CSV, HTML и т.д.).
Вместо создания традиционного шаблона метода factory, я планировал добавить метод к телу констант перечисления, который создавал бы и возвращал соответствующий объект отчета.
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()
Я хотел получить мнение других относительно использования этого подхода. Что ты думаешь об этом? Предпочитаете ли вы какой-либо другой подход, и если да, то почему?
Спасибо
Ответы
Ответ 1
Я думаю, что оба подхода в порядке, но если вы не хотите знать, какой отчет вы генерируете, я считаю, что подход 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();
Итак, если вы полагаетесь на полиморфизм, вам не нужно будет просить factory явно получить CVS/HTML/PDF, оставив эту работу самому Enum. Но, конечно, есть ситуации, когда вам может понадобиться использовать тот или иной, хотя я обычно использую подход enum регулярно.
Ответ 2
Какое преимущество вы получаете, используя перечисление, например, для создания отчета? Если бы у вас был factory -метод, вы бы создали экземпляр CSVReport (скажем), как показано ниже:
Report csvReport = ReportFactory.createCSVReport();
код > который, я думаю, передает намерение лучше, чем перечисление. Насколько я понимаю, перечисления представляют собой фиксированный набор констант, и использование его в качестве создания factory для экземпляра (хотя и работает) кажется мне неправильным использованием намерения Enumeration.
Ответ 3
Посмотрите Enum с шаблоном посетителя. С помощью этого подхода вы сможете динамически добавлять функциональность в перечисление без необходимости загрязнять само перечисление.
Ответ 4
Джошуа Блох (признанный эксперт по Java) на самом деле рекомендует этот подход в своей книге "Эффективная Java 2nd Edition" на стр. 17: Принудительное использование свойства singleton с приватным
конструктор или тип перечисления.