конфігурація програм
Навіщо потрібно конфігурування?
Професійним програмістам це питання здасться дивним. У початківців ж часто спостерігається явне нерозуміння важливості цієї можливості. При цьому виходить програма, схожа на кам'яну брилу з висіченими на ній написами - якщо захочеться змінити напис, то доведеться робити новий камінь.
Є й інша крайність - коли практично все виноситься в настройки. Такі програми нагадують розлиту рідину, а щоб змусити її працювати треба прочитати толмуд опису та налаштувати кілька сотень параметрів, до того ж часто взаємопов'язаних протиприродним чином.
Як завжди потрібно знайти золоту середину - з одного боку треба постаратися задовольнити різні примхи користувачів, з іншого боку потрібно зробити так, щоб більшості користувачів нічого налаштовувати не довелося.
Що саме варто налаштовувати.
Наприклад, досить часто зустрічається ситуація - настройка з'єднання з БД. Початківці програмісти часто пишуть щось подібне:
Таким чином програма прив'язується до конкретного JDBC драйверу. Використовувати інший драйвер, наприклад замінити міст на RMI-проксі або, в разі Oracle, OCI на Thin без перекомпіляції вже не можна.
Способи зберігання налаштувань.
В об'єктному програмуванні все представляється у вигляді об'єктів. Налаштування найкраще при цьому розглядати як властивості певних об'єктів, які зберігаються в файлах конфігурацій. Те, яким чином ці настройки зчитуються і записуються тісно взаємопов'язано з форматом файлів і обраної стратегією адміністрування. Розглянемо ідеальний варіант:- Настроюється об'єкт не повинен містити знань про формат файлів і способі читання / запису. Це дозволило б, в разі необхідності, замінити один спосіб іншим.
- Більшість налаштувань повинні виконуватися за допомогою програми (підпункт меню або окрема програма настройки). Це сильно полегшує життя людини, який займається адмініструванням. У більшості "юніксоід" це може викликати нерозуміння :-), але редагуванням текстових файлів в сучасному світі в багатьох випадках не обійтися.
- Повинно бути встановлено розумне умовчання для відсутніх параметрів. Іншими словами - необхідно, щоб більшості користувачів для запуску програми потрібно було б зробити мінімум налаштувань. Як правило це залишає сприятливе перше враження про програму, а часто саме воно - найважливіше.
На жаль цей ідеальний варіант досить важко зробити на практиці. Перша вимога передбачає розробку універсального механізму збереження об'єктів. Такі системи вже є готові, але часто вони не підходять за тими чи іншими параметрами. Розробити ж самому таку систему - далеко не кожному під силу.
Розумне ж замовчування для параметрів часто просто неможливо уявити. Наприклад, що поставити в якості імені SMTP-сервера? У разі Unix-систем можна спробувати поставити localhost, але для Windows-світу це рідко кому підійде.
Розглянемо найбільш поширені варіанти:
Ini-файли.
Ini-файли - це був найпоширеніший варіант в епоху Windows 3.x. Зараз в віндовий програмах він став витіснятися зберіганням налаштувань в реєстрі. Проте ini - це один з найпростіших варіантів зберігання налаштувань. На жаль досить часто ця простота змушує вдаватися до різному роду хитрощів. Приклад типового ini-файлу:
У Java немає стандартного класу для читання ini-файлів, але це не проблема. Оскільки формат дуже простий, його легко зробити самому:
Файли Properties.
Цей формат поширений в Unix-світі. Він ще простіше ini-файлів, тому що в ньому відсутнє поняття секцій - все складається з ключів і значень. Приклад типового файлу:
У Java є готовий клас для читання / запису таких файлів (java.util.Properties), але з ним є деякі проблеми. По-перше для читання неможливо задати кодування файлу, а це означає проблеми з українськими літерами. По-друге стандартна функція запису зберігає дані в порядку проходження хеш-значень ключів, що означає - як їй більше сподобається. Але це теж легко вирішується - достатньо написати свою Новомосковсклку / писалки.
XML-файли.
Цей формат підходить для багатьох цілей, в тому числі і для зберігання налаштувань. XML-формат орієнтований на деревовидні структури, що досить природно відображається на об'єкти. Приклад типового файлу:
Для читання і запису таких файлів призначені спеціальні бібліотеки - так звані XML-парсер. Таких парсеров вже зроблено досить багато, так що писати його самому немає великого сенсу - достатньо лише підібрати підходящий. Для парсеров було розроблено два стандартних програмних інтерфейсу - подієвий (SAX) і ієрархічний (DOM). Є також і парсери зі своїм інтерфейсом. Розмір jar-а з парсером може варіюватися від декількох кілобайт до мегабайта - залежно від підтримуваних інтерфейсів і можливостей.
Для XML також написано кілька бібліотек для універсального збереження (сериализации) об'єктів в файлах XML. Такі бібліотеки дозволяють відокремити алгоритм збереження від самого об'єкта, а це, як уже згадувалося, має багато плюсів.
Серіалізация.
Бази даних.
Використання скриптів - це один з найбільш екстремальних способів конфігурації. Вони дозволяють добитися максимальної гнучкості програми за рахунок винесення логіки назовні. У використанні скриптів треба теж знати міру - в кінці кінців замовник платить Вам за програму, вирішальну завдання, а не за ще один інтерпретатор або компілятор за який йому буде потрібно посадити ще одного програміста. А то виходить, як в тому анекдоті - яку програм не почнеш писати, все компілятор виходить.
Але часто без скриптів дійсно важко. Типові приклади - алгоритми імпорту / експорту, алгоритми перевірок даних. Ви можете підготувати стандартний набір, а далі налаштовувати скриптами під конкретні вимоги замовника.
Приклад програми з конфігурацією в XML.
Приклад вмісту конфігураційного файлу:
Як XML-парсера використовується Sun-івський парсер в режимі DOM. На такому простому прикладі не видно особливих переваг формату XML над тими ж файлами properties. Вони стають помітні тільки в досить складних програмах, де стає необхідно зберігати списки однотипних параметрів або ж вміст об'єктів з рівнем вкладеності два або більше.