Zastosowanie Factory method wzór:
public enum ReportType {EXCEL, CSV};
@Service
public class ReportFactory {
@Resource
private ExcelReport excelReport;
@Resource
private CSVReport csvReport
public Report forType(ReportType type) {
switch(type) {
case EXCEL: return excelReport;
case CSV: return csvReport;
default:
throw new IllegalArgumentException(type);
}
}
}
Typ enum
mogą być tworzone przez wiosnę, kiedy zadzwonić do kontrolera z ?type=CSV
raport:
class MyController{
@Resource
private ReportFactory reportFactory;
public HttpResponse getReport(@RequestParam("type") ReportType type){
reportFactory.forType(type);
}
}
Jednak ReportFactory
jest dość niezgrabny i wymaga modyfikacji za każdym razem, gdy dodajesz nowy typ raportu. Jeśli lista typów raportów, jeśli naprawiono, jest w porządku. Ale jeśli masz zamiar dodać więcej i więcej typów, to jest bardziej solidna realizacja:
public interface Report {
void generateFile();
boolean supports(ReportType type);
}
public class ExcelReport extends Report {
publiv boolean support(ReportType type) {
return type == ReportType.EXCEL;
}
//...
}
@Service
public class ReportFactory {
@Resource
private List<Report> reports;
public Report forType(ReportType type) {
for(Report report: reports) {
if(report.supports(type)) {
return report;
}
}
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
Dzięki tej implementacji dodając nowy typ raportu jest tak proste, jak dodanie nowego fasoli wykonawczych Report
i nową wartość ReportType
enum. Możesz uciec bez enum
i używając łańcuchów (może nawet nazw fasoli), jednak uważam, że silnie wpisywanie jest korzystne.
Ostatnia myśl: Report
nazwa jest trochę niefortunna. Report
klasa reprezentuje (bezstanowe?) Enkapsulację pewnej logiki (wzór Strategy), podczas gdy nazwa sugeruje, że zawiera wartość o wartości (dane). Sugerowałbym ReportGenerator
lub takie.
Dziękuję bardzo ... Tomasz spróbuje tego. Zmienię odpowiednio nazwę. –
Pracowałam jak wdzięk. Dziękuję bardzo za pokazanie opcji skalowalnej –
+1 – DecafCoder