Config Class / Struct: Pattern o Anti-Pattern? Alternative?

7

Se aggiungi nuove opzioni di configurazione a un programma, spesso può avere un sacco di effetti a catena in termini di ottenere le opzioni dove devono essere applicate. Ci sono tre modi fondamentali per affrontare questo che sono a conoscenza di:

  1. Passa tutte le impostazioni di configurazione alle parti del tuo programma che ne hanno bisogno esplicitamente come primitive. Questo è il modo più esplicito e il modo in cui le cose si disaccoppiano di più. Lo svantaggio è che è al tempo stesso prolisso e fragile.

  2. Rendi globali e statiche le impostazioni di configurazione più utilizzate. Questo è il modo più semplice ma introduce un'azione a distanza, ostacola la testabilità e presuppone che la configurazione sia realmente globale (che vorresti solo una configurazione in un dato momento).

  3. Crea una classe di configurazione / struct che contenga tutte le opzioni di configurazione per l'intero programma o per ogni problema principale all'interno del programma, quindi passa questo in modo esplicito. Questo è meno esplicito di (1) ma più esplicito di (2). Se si desidera modificare un'impostazione solo per una chiamata di funzione, è possibile clonare l'oggetto config e modificare questo valore. Questo è utile sia nel test che nella pratica. Tuttavia, si finisce comunque per passare potenzialmente tonnellate di informazioni a una funzione che non necessita e la modifica di un valore nella classe di configurazione / struct può ancora causare un'azione a distanza.

Considereresti (3) un pattern o un anti-pattern? Se si tratta di un anti-pattern, cosa fai invece?

    
posta dsimcha 18.10.2011 - 17:04
fonte

5 risposte

4

La soluzione migliore sarebbe quella di creare diverse interfacce di configurazione e implementarle come desideri. Ciò limita entrambi l'accessibilità e mantiene le cose localizzate. Tuttavia, è troppo difficile per essere valsa la pena semplicemente buttando tutto il config in una singola classe e passare a un problema con molto più gravitas. Questa è la configurazione, non quella di UtterlyCrucialAlwaysChangingClass, praticamente rimarrà la stessa. Fintanto che non rendi tutto globale e l'implementazione è coerente, non me ne preoccuperei.

    
risposta data 18.10.2011 - 17:27
fonte
1

Preferisco l'opzione 1 perché il disaccoppiamento consente una verifica più semplice e le impostazioni di configurazione di cui l'oggetto dipende sono esplicitate. Se un oggetto richiede un'impostazione di configurazione, fornirlo esplicitamente all'oggetto tramite un argomento costruttore o un metodo setter. Riduci la verbosità utilizzando un framework di iniezione delle dipendenze per iniettare tali impostazioni di configurazione nell'oggetto.

    
risposta data 18.10.2011 - 17:45
fonte
0

Immagina se il tuo file di configurazione fosse scritto in XML. Potresti quindi passare i frammenti di questo XML a ciascuno dei tuoi componenti, in modo che ottengano i loro dati di configurazione.

Se si utilizza .NET, è possibile creare classi con DataContracts che è possibile utilizzare XmlSerialiser per creare una gerarchia di oggetti dall'Xml di configurazione e passare questi oggetti come configurazione.

Questo ti introduce al prossimo problema. I dati di configurazione hanno tre parti differenti. La configurazione dell'applicazione strutturale che organizza le tue librerie di codici per comportarsi come questo prodotto specifico. Impostazioni di configurazione del sito che contengono le impostazioni specifiche dell'installazione e le preferenze utente / i dati delle impostazioni che varia con ciascun utente sul sistema.

Sapendo quale parte è e mantenendo separate queste impostazioni dei dati, l'installazione degli aggiornamenti sarà molto più semplice (senza perdere le impostazioni dei clienti)

    
risposta data 18.10.2011 - 17:20
fonte
0

Renderei la classe nell'opzione # 3 statica. Quindi invece di

//create SomeCl
Foo f = new Foo();
f.setConfigInst(cfg);
...
...
//Inside Foo
public void setConfig(MyAppConfig c) { localCfg = c; }
...
//somewhere else:
x = localCfg.getConfigForX();

Puoi semplicemente avere:

//Inside Foo
x = MyAppConfig.getConfigForX();

Lascia che i dettagli del caricamento / salvataggio dei dati di configurazione avvengano all'interno della classe MyAppConfig . E naturalmente potresti avere variazioni più complesse, come classi diverse per scopi diversi.

L'unico caso in cui questo approccio sarebbe un problema sarebbe se per qualche motivo dovessi lavorare su più istanze di configurazioni differenti allo stesso tempo , anche se devo ancora imbattermi in tale situazione.

    
risposta data 18.10.2011 - 17:28
fonte
0

Sto lavorando a un progetto in cui utilizziamo l'approccio "3 livelli (interfaccia, business logic, accesso ai dati)". L'applicazione può essere un server web multiutente o un server client.

Lavoriamo con 3 diverse configurazioni, la prima specifica per la P.C., mentre l'utente sta lavorando. Il secondo specifico per l'utente corrente e una terza configurazione globale per tutti gli utenti e amp; app client.

Ogni configurazione è rappresentata in ogni istanza dell'applicazione da un oggetto.

Questo approccio può aiutare il tuo progetto.

    
risposta data 19.10.2011 - 00:58
fonte

Leggi altre domande sui tag