Простой способ сохранить настройки приложения Java представлен текстовым файлом с расширением «.properties», содержащим идентификатор каждого параметра, связанного с конкретным значением (это может быть число, строка, дата и т. Д.) , C # использует аналогичный подход, но текстовый файл должен называться «App.config». В обоих случаях в исходном коде вы должны инициализировать определенный класс для чтения настроек: у этого класса есть метод, который возвращает значение (в виде строки), связанное с указанным идентификатором настройки.
// 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"];
// ...
В обоих случаях мы должны проанализировать строки, загруженные из файла конфигурации, и назначить преобразованные значения связанным типизированным объектам (ошибки синтаксического анализа могут возникнуть на этом этапе). После шага синтаксического анализа мы должны убедиться, что значения настроек принадлежат определенной области действия: например, максимальный размер очереди должен быть положительным значением, некоторые значения могут быть связаны (пример: min <max ), и так далее.
Предположим, что приложение должно загрузить настройки сразу после его запуска: другими словами, первая операция, выполняемая приложением, заключается в загрузке настроек. Любые недопустимые значения параметров должны быть автоматически заменены значениями по умолчанию: если это происходит с группой связанных параметров, все эти параметры устанавливаются со значениями по умолчанию.
Самый простой способ выполнить эти операции - создать метод, который сначала анализирует все параметры, затем проверяет загруженные значения и, наконец, устанавливает любые значения по умолчанию. Однако обслуживание будет затруднено, если вы используете этот подход: по мере того, как количество параметров увеличивается при разработке приложения, становится все труднее обновлять код.
Чтобы решить эту проблему, я подумал об использовании шаблона Template Method следующим образом.
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;
}
}
Проблема в том, что таким образом нам нужно создать новый класс для каждого параметра, даже для одного значения. Существуют ли другие решения этой проблемы?
В итоге:
- Простота обслуживания: например, добавление одного или нескольких параметров.
- Расширяемость: первая версия приложения может считывать один файл конфигурации, но более поздние версии могут дать возможность многопользовательской настройки (администратор устанавливает базовую конфигурацию, пользователи могут устанавливать только определенные настройки и т. Д.).
- Объектно-ориентированный дизайн.