Простий спосіб збереження налаштувань програми 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 ), і так далі.
Припустимо, що програма повинна завантажити налаштування, як тільки вона починається: іншими словами, перша операція, яку виконує програма, - це завантаження налаштувань. Будь-які недійсні значення параметрів повинні автоматично замінюватися значеннями за замовчуванням: якщо це трапляється з групою пов’язаних налаштувань, ці налаштування встановлюються за замовчуванням.
Найпростіший спосіб виконати ці операції - створити метод, який спочатку аналізує всі налаштування, потім перевіряє завантажені значення і, нарешті, встановлює будь-які значення за замовчуванням. Однак технічне обслуговування складно, якщо ви використовуєте такий підхід: у міру збільшення кількості налаштувань під час розробки програми додавати код стає все складніше.
Для того, щоб вирішити цю проблему, я подумав про використання шаблону методу шаблонів таким чином.
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;
}
}
Проблема полягає в тому, що таким чином нам потрібно створити новий клас для кожного параметра, навіть для одного значення. Чи є інші варіанти вирішення подібної проблеми?
Підсумовуючи:
- Легке обслуговування: наприклад, додавання одного або декількох параметрів.
- Розширюваність: перша версія програми може прочитати один файл конфігурації, але пізніші версії можуть дати можливість налаштування для багатьох користувачів (адміністратор встановлює базову конфігурацію, користувачі можуть встановлювати лише певні налаштування тощо).
- Об'єктно-орієнтований дизайн.