Una manera simple de mantener la configuración de una aplicación Java está representada por un archivo de texto con la extensión ".properties" que contiene el identificador de cada configuración asociada con un valor específico (este valor puede ser un número, cadena, fecha, etc.) . C # utiliza un enfoque similar, pero el archivo de texto debe llamarse "App.config". En ambos casos, en el código fuente debe inicializar una clase específica para leer la configuración: esta clase tiene un método que devuelve el valor (como cadena) asociado con el identificador de configuración especificado.
// 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"];
// ...
En ambos casos, deberíamos analizar las cadenas cargadas desde el archivo de configuración y asignar los valores convertidos a los objetos mecanografiados relacionados (podrían ocurrir errores de análisis durante esta fase). Después del paso de análisis, debemos verificar que los valores de configuración pertenecen a un dominio específico de validez: por ejemplo, el tamaño máximo de una cola debe ser un valor positivo, algunos valores pueden estar relacionados (ejemplo: min <max ), y así.
Suponga que la aplicación debe cargar la configuración tan pronto como se inicia: en otras palabras, la primera operación realizada por la aplicación es cargar la configuración. Cualquier valor no válido para la configuración debe reemplazarse automáticamente con los valores predeterminados: si esto le sucede a un grupo de configuraciones relacionadas, esas configuraciones se establecerán con valores predeterminados.
La forma más fácil de realizar estas operaciones es crear un método que primero analice todas las configuraciones, luego verifique los valores cargados y finalmente establezca los valores predeterminados. Sin embargo, el mantenimiento es difícil si utiliza este enfoque: a medida que aumenta el número de configuraciones mientras se desarrolla la aplicación, se vuelve cada vez más difícil actualizar el código.
Para resolver este problema, pensé en usar el patrón Método de plantilla , como sigue.
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;
}
}
El problema es que de esta manera necesitamos crear una nueva clase para cada configuración, incluso para un solo valor. ¿Hay otras soluciones para este tipo de problema?
En resumen:
- Fácil mantenimiento: por ejemplo, la adición de uno o más parámetros.
- Extensibilidad: una primera versión de la aplicación podría leer un solo archivo de configuración, pero las versiones posteriores pueden dar la posibilidad de una configuración multiusuario (el administrador configura una configuración básica, los usuarios pueden establecer solo ciertas configuraciones, etc.).
- Diseño orientado a objetos.