2011-09-24 12 views
7

Chcę wstrzyknąć fasolę na podstawie parametru String przekazanego z klienta.Warunkowe wstrzykiwanie fasoli

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() { 
    } 
} 

Chcę zgłosić wystąpienie być wstrzykiwany w oparciu o parametr przekazany. Każda pomoc byłaby bardzo przydatna. Dzięki z góry

Odpowiedz

13

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.

+0

Dziękuję bardzo ... Tomasz spróbuje tego. Zmienię odpowiednio nazwę. –

+0

Pracowałam jak wdzięk. Dziękuję bardzo za pokazanie opcji skalowalnej –

+0

+1 – DecafCoder