Un modo semplice per mantenere le impostazioni di un'applicazione Java è rappresentato da un file di testo con estensione ".properties" contenente l'identificatore di ciascuna impostazione associata a un valore specifico (questo valore può essere un numero, una stringa, una data, ecc.) . C # usa un approccio simile, ma il file di testo deve essere chiamato "App.config". In entrambi i casi, nel codice sorgente è necessario inizializzare una classe specifica per la lettura delle impostazioni: questa classe ha un metodo che restituisce il valore (come stringa) associato all'identificatore di impostazione specificato.
// Java example
Properties config = new Properties();
config.load(...);
String valueStr = config.getProperty("listening-port");
// ...
// C# example
NameValueCollection setting = ConfigurationManager.AppSettings;
string valueStr = setting["listening-port"];
// ...
In entrambi i casi dovremmo analizzare le stringhe caricate dal file di configurazione e assegnare i valori convertiti ai relativi oggetti digitati (durante questa fase potrebbero verificarsi errori di analisi). Dopo la fase di analisi, dobbiamo verificare che i valori di impostazione appartengano a un dominio specifico di validità: ad esempio, la dimensione massima di una coda deve essere un valore positivo, alcuni valori potrebbero essere correlati (esempio: min <max ), e così via.
Supponiamo che l'applicazione dovrebbe caricare le impostazioni non appena si avvia: in altre parole, la prima operazione eseguita dall'applicazione è caricare le impostazioni. Eventuali valori non validi per le impostazioni devono essere sostituiti automaticamente con valori predefiniti: se ciò accade a un gruppo di impostazioni correlate, tali impostazioni vengono tutte impostate con valori predefiniti.
Il modo più semplice per eseguire queste operazioni è creare un metodo che prima analizza tutte le impostazioni, quindi controlla i valori caricati e infine imposta tutti i valori predefiniti. Tuttavia, la manutenzione è difficile se si utilizza questo approccio: poiché il numero di impostazioni aumenta durante lo sviluppo dell'applicazione, diventa sempre più difficile aggiornare il codice.
Per risolvere questo problema, avevo pensato di utilizzare il modello Metodo modello, come segue.
public abstract class Setting
{
protected abstract bool TryParseValues();
protected abstract bool CheckValues();
public abstract void SetDefaultValues();
/// <summary>
/// Template Method
/// </summary>
public bool TrySetValuesOrDefault()
{
if (!TryParseValues() || !CheckValues())
{
// parsing error or domain error
SetDefaultValues();
return false;
}
return true;
}
}
public class RangeSetting : Setting
{
private string minStr, maxStr;
private byte min, max;
public RangeSetting(string minStr, maxStr)
{
this.minStr = minStr;
this.maxStr = maxStr;
}
protected override bool TryParseValues()
{
return (byte.TryParse(minStr, out min)
&& byte.TryParse(maxStr, out max));
}
protected override bool CheckValues()
{
return (0 < min && min < max);
}
public override void SetDefaultValues()
{
min = 5;
max = 10;
}
}
Il problema è che in questo modo dobbiamo creare una nuova classe per ogni impostazione, anche per un singolo valore. Esistono altre soluzioni a questo tipo di problema?
In sintesi:
- Facile manutenzione: ad esempio l'aggiunta di uno o più parametri.
- Estensibilità: una prima versione dell'applicazione potrebbe leggere un singolo file di configurazione, ma le versioni successive potrebbero dare la possibilità di una configurazione multiutente (admin imposta una configurazione di base, gli utenti possono impostare solo determinate impostazioni, ecc.).
- Design orientato agli oggetti.