2011-09-24 17 views
7

クライアントから渡されたStringパラメータに基づいてBeanを挿入したいと思います。Beanの条件付き注入

public interface Report { 
    generateFile(); 
} 

public class ExcelReport extends Report { 
    //implementation for generateFile 
} 

public class CSVReport extends Report { 
    //implementation for generateFile 
} 

class MyController{ 
    Report report; 
    public HttpResponse getReport() { 
    } 
} 

渡されたパラメータに基づいてレポートインスタンスを挿入する必要があります。どんな助けでも大いに賛成するでしょう。おかげで、事前に

答えて

13

使用は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かそれを提案するでしょう。

+0

ありがとうTomasz ...これを試してみましょう。それに応じて名前を変更します。 –

+0

チャームのように働いています。スケーラブルなオプションを表示するために大変ありがとうございます –

+0

+1 – DecafCoder