Use the Factory method :
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); } } }
The enum report type can be created by Spring when invoking your controller using ?type=CSV :
class MyController{ @Resource private ReportFactory reportFactory; public HttpResponse getReport(@RequestParam("type") ReportType type){ reportFactory.forType(type); } }
However, ReportFactory pretty awkward and needs to be changed every time you add a new report type. If the report list is displayed, if it is corrected, this is normal. But if you plan to add more and more types, this is a more robust implementation:
public interface Report { void generateFile(); boolean supports(ReportType type); } public class ExcelReport extends Report { publiv boolean support(ReportType type) { return type == ReportType.EXCEL; }
With this implementation, adding a new report type is as simple as adding a new bean for the Report implementation and a new ReportType enumeration ReportType . You can leave without enum and use strings (maybe even bean names), however I found that I am gaining a lot of usefulness.
One final thought: Report name is a bit unsuccessful. Report class represents (stagnant?) The encapsulation of some logic ( Strategy pattern, whereas the name assumes that it encapsulates the value (data). I would suggest ReportGenerator or such.
Tomasz Nurkiewicz
source share