Come gestire diverse configurazioni con proprietà non sovrapposte?

5

Sto lavorando a un progetto basato sulla tecnologia Java EE. Per prima cosa vorrei dirti cosa voglio raggiungere, quindi cosa ho già provato.

Task:

Immagina due tipi di configurazioni, che vuoi scegliere e modificare / definire nell'applicazione JEE tramite le voci della GUI. Config A è per la comunicazione con Sistema A e Config B è per la comunicazione con Sistema B .

Config A ha alcune proprietà uguali a Config B , ma le proprietà stesse differiscono in qualche modo (esempio: enumerazioni). Inoltre Config A e B ognuno ha più proprietà che non hanno in comune. Ora, se l'utente dell'applicazione inserisce una configurazione (A o B), dovrebbe essere possibile accedere in modo semplice e generale a tutti i metodi / proprietà date delle configurazioni, senza chiedere sempre quale tipo di configurazione è stato selezionato. Come si può accedere in particolare alle proprietà / metodi che differiscono, in modo facile e non ridondante?

Impostazione corrente:

Poiché cerco di ridurre il codice ridondante, ho creato una classe astratta che definisce una configurazione generale, chiamiamola " GeneralConfiguration ".

Config A e B ogni estensione GeneralConfiguration . Per ogni proprietà "condivisa", GeneralConfiguration definisce un'interfaccia. Ogni interfaccia è implementata da diverse enumerazioni, che rappresentano le voci possibili per la configurazione generale a seconda del tipo di configurazione (A o B).

Penso che la mia configurazione non sia ottimale. Quindi cosa ne pensi, come gestire questo tipo di compito?

    
posta qecce 22.07.2016 - 14:22
fonte

2 risposte

3

Penso che la domanda sia interessante. Non è il problema in sé. È dovuto all'abuso dell'eredità. Un cattivo uso molto comune.

Perché lo dico?

Because I try to reduce redundant code I created an abstract class defining a general configuration, let's call it "GeneralConfiguration".

Questa è una delle peggiori ragioni per usare l'ereditarietà. L'obiettivo al di sotto delle classi astratte è molto più sofisticato di salvarci dalla duplicazione del codice .

For each "shared" property GeneralConfiguration defines an interface

Qui i dettagli di implementazione sono stati trasferiti a qualcosa che doveva essere astratto . Questo uccide le classi astratte che fanno bene, ci distraggono dai dettagli.

L'unica cosa in comune tra A e B è che, concettualmente , entrambe sono configurazioni , ma qui terminano le loro somiglianze.

Com'è?

Now, if the application user enters one configuration(A or B) it should be possible to access in a general and easy way all given methods/properties of the configurations.

Dal design entrambi si sono trasformati in qualcosa di diverso. Entrambi sono stati progettati come due componenti diversi e ora stiamo cercando di risolverlo con l'ereditarietà. L'ereditarietà non funziona in questo modo.

Sulla carta, entrambi potrebbero avere lo stesso significato e lo scopo, ma tale funzione non è stata trasferita al design.

Se vogliamo astrarci dai "dettagli" (A o B), la configurazione dovrebbe essere totalmente agnostica per loro .

Esempio:

public Configuration {
  Map<enum,Object> properties;

  public Configuration(){
        properties = new HashMap<enum,Object>();
  }

  public Object getProperty(enum propertyName){
         return properties.get(propertyName);
  }

  public void setProperty(enum propertyName, Object value){
        properties.put(propertyName, value);
  }
 }

Ora, non c'è né A né B (e l'ereditarietà diventa inutile) .

Come impiantiamo A e B?

Ora possiamo implementare "dettagli" sull'astrazione. Ad esempio, implementando il modello di delega

public ConfigA {
    Configuration config;

  public ConfigA(Configuration config){
      this.config = config;
  }

 public String getA(){
       return (String)  config.getProperty(MyEnumA.A);
  }

  public void setA(String value){
      config.setProperty(MyEnumA.A,value);
  }
      ...
}

Se abbiamo bisogno di "dettagli" usiamo ConfigA / ConfigB . Usiamo Configurazione per il resto.

Nota: quando dico astrazione non mi riferisco solo alle classi astratte. Mi riferisco al concetto.

    
risposta data 19.11.2016 - 21:39
fonte
0

Penso che il modello Builder possa aiutarti.

public class ConfigBuilder 
{
    public void SetPropertyA(string a)
    public void SetPropertyB(int b)
    public GeneralConfiguration Build()
}

L'interfaccia utente può interagire con i metodi esposti dall'oggetto ConfigBuilder . Una volta che l'utente è OK, verrà invocato il metodo Build per determinare se ConfigA o ConfigB verrà creato in base alle proprietà impostate nell'oggetto ConfigBuilder .

    
risposta data 22.07.2016 - 14:51
fonte

Leggi altre domande sui tag