使用は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);
}
}
}
レポートタイプenum
はあなたが?type=CSV
とあなたのコントローラを呼び出すとき春によって作成することができます。
class MyController{
@Resource
private ReportFactory reportFactory;
public HttpResponse getReport(@RequestParam("type") ReportType type){
reportFactory.forType(type);
}
}
しかしReportFactory
はかなり不器用で、修正が必要新しいレポートタイプを追加するたびに固定の場合はレポートの種類がリストにあれば問題ありません。しかし、あなたは、より多くの種類を追加することを計画している場合、これは、より堅牢な実装である:
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);
}
}
この実装では、新しいレポートの種類を追加することでReport
を実装する新しいBeanと新しいReportType
列挙値を追加するのと同じくらい簡単です。 enum
を使わずに文字列(たぶんBean名)を使ってもらえますが、強くタイプすると有益です。
最後の考え:Report
名前は少し残念です。 Report
クラスは、一部のロジック(Strategyパターン)の(ステートレス?)カプセル化を表しますが、その名前は値(データ)をカプセル化することを示しています。私はReportGenerator
かそれを提案するでしょう。
ありがとうTomasz ...これを試してみましょう。それに応じて名前を変更します。 –
チャームのように働いています。スケーラブルなオプションを表示するために大変ありがとうございます –
+1 – DecafCoder