2017-03-31 2 views
0

Es gibt eine Klasse viele Getter und Setter enthält:Wie man einen dynamischen Methodenaufruf macht?

@Entity 
@Table(name = "valeur_indicateur") 
public class ValeurIndicateur { 

    @Id 
    @SequenceGenerator(name="s_valeur_indicateur", sequenceName="s_valeur_indicateur", allocationSize=1) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_valeur_indicateur") 
    @Column(name = "val_indi_code") 
    private Integer code; 

    @ManyToOne 
    @JoinColumn(name = "indi_code") 
    private Indicateur indicateur; 

    @ManyToOne 
    @JoinColumn(name = "peri_mes_code") 
    private PeriodiciteMesure periodicite_mesure; 

    @Column(name = "val_indi_cible_1") 
    private String cible_1; 

    @Column(name = "val_indi_cible_2") 
    private String cible_2; 

    @Column(name = "val_indi_cible_3") 
    private String cible_3; 

    @Column(name = "val_indi_cible_4") 
    private String cible_4; 

    @Column(name = "val_indi_cible_5") 
    private String cible_5; 

    @Column(name = "val_indi_cible_6") 
    private String cible_6; 

    @Column(name = "val_indi_cible_7") 
    private String cible_7; 

    @Column(name = "val_indi_cible_8") 
    private String cible_8; 

    @Column(name = "val_indi_cible_9") 
    private String cible_9; 

    @Column(name = "val_indi_cible_10") 
    private String cible_10; 

    @Column(name = "val_indi_cible_11") 
    private String cible_11; 

    @Column(name = "val_indi_cible_12") 
    private String cible_12; 

    @Column(name = "val_indi_realise_1") 
    private String realise_1; 

    @Column(name = "val_indi_realise_2") 
    private String realise_2; 

    @Column(name = "val_indi_realise_3") 
    private String realise_3; 

    @Column(name = "val_indi_realise_4") 
    private String realise_4; 

    @Column(name = "val_indi_realise_5") 
    private String realise_5; 

    @Column(name = "val_indi_realise_6") 
    private String realise_6; 

    @Column(name = "val_indi_realise_7") 
    private String realise_7; 

    @Column(name = "val_indi_realise_8") 
    private String realise_8; 

    @Column(name = "val_indi_realise_9") 
    private String realise_9; 

    @Column(name = "val_indi_realise_10") 
    private String realise_10; 

    @Column(name = "val_indi_realise_11") 
    private String realise_11; 

    @Column(name = "val_indi_realise_12") 
    private String realise_12; 

    @Column(name = "val_indi_taux") 
    private Integer taux; 

    public ValeurIndicateur() { 
     super(); 
     // TODO Auto-generated constructor stub 
    } 

    public ValeurIndicateur(Integer code) { 
     super(); 
    } 

    public Integer getCode() { 
     return code; 
    } 

    public void setCode(Integer code) { 
     this.code = code; 
    } 

    public Indicateur getIndicateur() { 
     return indicateur; 
    } 

    public void setIndicateur(Indicateur indicateur) { 
     this.indicateur = indicateur; 
    } 

    public PeriodiciteMesure getPeriodicite_mesure() { 
     return periodicite_mesure; 
    } 

    public void setPeriodicite_mesure(PeriodiciteMesure periodicite_mesure) { 
     this.periodicite_mesure = periodicite_mesure; 
    } 

    public String getCible_1() { 
     return cible_1; 
    } 

    public void setCible_1(String cible_1) { 
     this.cible_1 = cible_1; 
    } 

    public String getCible_2() { 
     return cible_2; 
    } 

    public void setCible_2(String cible_2) { 
     this.cible_2 = cible_2; 
    } 

    public String getCible_3() { 
     return cible_3; 
    } 

    public void setCible_3(String cible_3) { 
     this.cible_3 = cible_3; 
    } 

    public String getCible_4() { 
     return cible_4; 
    } 

    public void setCible_4(String cible_4) { 
     this.cible_4 = cible_4; 
    } 

    public String getCible_5() { 
     return cible_5; 
    } 

    public void setCible_5(String cible_5) { 
     this.cible_5 = cible_5; 
    } 

    public String getCible_6() { 
     return cible_6; 
    } 

    public void setCible_6(String cible_6) { 
     this.cible_6 = cible_6; 
    } 

    public String getCible_7() { 
     return cible_7; 
    } 

    public void setCible_7(String cible_7) { 
     this.cible_7 = cible_7; 
    } 

    public String getCible_8() { 
     return cible_8; 
    } 

    public void setCible_8(String cible_8) { 
     this.cible_8 = cible_8; 
    } 

    public String getCible_9() { 
     return cible_9; 
    } 

    public void setCible_9(String cible_9) { 
     this.cible_9 = cible_9; 
    } 

    public String getCible_10() { 
     return cible_10; 
    } 

    public void setCible_10(String cible_10) { 
     this.cible_10 = cible_10; 
    } 

    public String getCible_11() { 
     return cible_11; 
    } 

    public void setCible_11(String cible_11) { 
     this.cible_11 = cible_11; 
    } 

    public String getCible_12() { 
     return cible_12; 
    } 

    public void setCible_12(String cible_12) { 
     this.cible_12 = cible_12; 
    } 

    public String getRealise_1() { 
     return realise_1; 
    } 

    public void setRealise_1(String realise_1) { 
     this.realise_1 = realise_1; 
    } 

    public String getRealise_2() { 
     return realise_2; 
    } 

    public void setRealise_2(String realise_2) { 
     this.realise_2 = realise_2; 
    } 

    public String getRealise_3() { 
     return realise_3; 
    } 

    public void setRealise_3(String realise_3) { 
     this.realise_3 = realise_3; 
    } 

    public String getRealise_4() { 
     return realise_4; 
    } 

    public void setRealise_4(String realise_4) { 
     this.realise_4 = realise_4; 
    } 

    public String getRealise_5() { 
     return realise_5; 
    } 

    public void setRealise_5(String realise_5) { 
     this.realise_5 = realise_5; 
    } 

    public String getRealise_6() { 
     return realise_6; 
    } 

    public void setRealise_6(String realise_6) { 
     this.realise_6 = realise_6; 
    } 

    public String getRealise_7() { 
     return realise_7; 
    } 

    public void setRealise_7(String realise_7) { 
     this.realise_7 = realise_7; 
    } 

    public String getRealise_8() { 
     return realise_8; 
    } 

    public void setRealise_8(String realise_8) { 
     this.realise_8 = realise_8; 
    } 

    public String getRealise_9() { 
     return realise_9; 
    } 

    public void setRealise_9(String realise_9) { 
     this.realise_9 = realise_9; 
    } 

    public String getRealise_10() { 
     return realise_10; 
    } 

    public void setRealise_10(String realise_10) { 
     this.realise_10 = realise_10; 
    } 

    public String getRealise_11() { 
     return realise_11; 
    } 

    public void setRealise_11(String realise_11) { 
     this.realise_11 = realise_11; 
    } 

    public String getRealise_12() { 
     return realise_12; 
    } 

    public void setRealise_12(String realise_12) { 
     this.realise_12 = realise_12; 
    } 

    public Integer getTaux() { 
     return taux; 
    } 

    public void setTaux(Integer taux) { 
     this.taux = taux; 
    } 

    @Override 
    public String toString() { 
     // TODO Auto-generated method stub 
     return code.toString(); 
    } 

} 

Ich möchte rufen Sie die Setter setCible_ von 1 bis 12:

@RequestMapping(value = "/insertIndicateur", method = RequestMethod.POST) 
public ModelAndView insertIndicateur(@ModelAttribute("indicateur_formulaire") Indicateur indicateur, 
            @RequestParam int f_objectif, 
            @RequestParam int f_nature_indicateur, 
            @RequestParam String f_periodicite_mesure, 
            @RequestParam String f_type_sortie, 
            @RequestParam String acteur_saisie, 
            @RequestParam String acteur_verif, 
            @RequestParam Map<String, String> params, 
            HttpServletRequest request, HttpSession session) { 

    indicateurDao.insert(indicateur, f_objectif, f_nature_indicateur, f_periodicite_mesure, f_type_sortie, acteur_saisie, acteur_verif); 

    ValeurIndicateur valeurIndicateur = new ValeurIndicateur(); 

    switch(f_periodicite_mesure) { 
     case "ANN": 
      valeurIndicateur.setCible_1(params.get("val_indi_cible_1")); 
      break; 
     case "SEM": 
      valeurIndicateur.setCible_1(params.get("val_indi_cible_1")); 
      valeurIndicateur.setCible_2(params.get("val_indi_cible_2")); 
      break; 
     case "TRI": 
      valeurIndicateur.setCible_1(params.get("val_indi_cible_1")); 
      valeurIndicateur.setCible_2(params.get("val_indi_cible_2")); 
      valeurIndicateur.setCible_3(params.get("val_indi_cible_3")); 
      valeurIndicateur.setCible_4(params.get("val_indi_cible_4")); 
      break; 
     case "MEN": 

      // here I want to loop from 1 to 12 and call dynamically valeurIndicateur.setCible_ 

      break; 
    } 

    valeurIndicateur.setIndicateur(indicateur); 
    valeurIndicateur.setPeriodicite_mesure(periodiciteMesureDao.get(f_periodicite_mesure)); 

    valeurIndicateurDao.insert(valeurIndicateur); 

    ModelAndView modelView = new ModelAndView("redirect:/elaboration/"); 

    return modelView; 

} 

Gibt es eine Möglichkeit, um dynamisch sie zu nennen?

+0

Für Getter & Setter, wenn ich Reflexion vermeiden möchte, erstelle ich manchmal eine schmutzig-aber-nützliche Methode getField (String fieldName) (und setField (String-Feld, Objekt Wert)) mit einem großen Schaltergehäuse. Sie müssen die Methode jedes Mal manuell bearbeiten, wenn Sie einen Getter hinzufügen, aber sie erledigt den Job. –

Antwort

1

Dynamisch kocht herunter, um die reflection Dienstprogramme zu verwenden.

Also ja; Mit Reflection können Sie Methoden mit dem Namen auf Ihrem Objekt valeurIndicateur aufrufen. Und natürlich können Sie diese Methodennamen mit einer Basiszeichenfolge erstellen, an die ein Index angehängt wird.

Aber dann kommt das mit der üblichen "Reflexionsrechnung"; da die Reflexion die Leistung und die Lesbarkeit/Robustheit des Codes in einem (manchmal sehr) negativen Weg beeinflusst.

In Ihrem Fall: Ich wundere mich, wenn Sie nicht eher in Nacharbeit Ihr ganzes Modell suchen sollten. Warum verwenden Sie explizit Namen wie c1, c2, c3, ...? Wäre es nicht sinnvoller, stattdessen eine Form von Liste/Array zu verwenden ?! Bedeutung: für mich scheint es als diese Frage ist ein Ergebnis einer schlechten Design-Entscheidung; und anstatt dieses wirkliche Problem zu beheben; Sie fragen "Wie lindere ich die Symptome?"

+0

Ich versetze den Downvote, weil ich der Notwendigkeit der Reflexion und der gut durchdachten Warnung über seine Kosten zustimme. Und ja, es könnte billigere Wege geben, das zu tun, was OP will, bevor man die großen Waffen herauszieht. –

2

Wenn Ihr Objekt mit der Spezifikation Java Beans, dann arbeitet (wie Sie Frühling verwenden), die BeanWrapper Schnittstelle ist wahrscheinlich die beste Wahl:

BeanWrapper beanWrapper = new BeanWrapperImpl(yourObject); 
Arrays.stream(beanWrapper.getPropertyDescriptors()) 
     .map(PropertyDescriptor::getName) 
     .forEach(name-> beanWrapper.setPropertyValue(name, attributes.get(name)) 
); 

Beachten Sie, dass die Java Beans Eigenschaftsnamen „foo“ Punkte auf der Methoden "setFoo" und "getFoo".

Oder, wenn Sie über die Attribute Karte iterieren wollen, tun Sie es wie folgt aus:

BeanWrapper beanWrapper = new BeanWrapperImpl(yourObject); 
attributes.forEach((k,v)->{ 
    if(beanWrapper.isWritableProperty(k)) beanWrapper.setPropertyValue(k,v); 
}); 

Eine andere Möglichkeit, ohne Reflexion eine hart codierte Karte mit BiConsumers haben, die die Methoden aufrufen, etwas dies wie:

static final Map<String, BiConsumer<YourClass,String>> PROPERTY_MAP; 
static { 
    Map<String, BiConsumer<YourClass,String>> map = new HashMap<>(); 
    map.put("val_indi_cible_1", YourClass::setCible_1); 
    map.put("val_indi_cible_2", YourClass::setCible_2); 
    map.put("val_indi_cible_3", YourClass::setCible_3); 
    map.put("val_indi_cible_4", YourClass::setCible_3); 
    map.put("val_indi_cible_5", YourClass::setCible_4); 
    map.put("val_indi_cible_6", YourClass::setCible_5); 
    // etc. 
    PROPERTY_MAP= Collections.unmodifiableMap(map); 
} 

nun in Ihrer Methode, können Sie etwas tun:

YourClass yourClass = new YourClass(); 
attributes.forEach((k, v) -> Optional.ofNullable(PROPERTY_MAP.get(k)) 
            .ifPresent(bc -> bc.accept(yourClass, v))); 

Erläuterung:

  • Iterate über Attribute
  • Für jeden Schlüssel zuordnen, ob es eine zugehörige Eigenschaft ist
  • Falls vorhanden, rufen Sie diese Eigenschaft

Vorteil: keine Reflexion, anständige Leistung, kompilieren-Zeit Sicherheit

Nachteil: Sie müssen die Eigenschaft Karte wann immer aktualisieren Sie fügen eine neue Methode hinzu

+0

betrifft es alle Attribute? – pheromix

+0

Wie ich es gemacht habe, iteriert es über die Klasseneigenschaften, aber Sie könnten natürlich über Ihre Attributzuordnung iterieren und trotzdem den BeanWrapper verwenden, um die Werte zuzuweisen –

+0

können Sie bitte Ihre Antwort entsprechend meinen Bedürfnissen aktualisieren, weil ich verloren habe:) – pheromix

Verwandte Themen