Информация об изменениях

Сообщение Re: лучшие практики для настроек-конфигов приложения.. от 31.03.2021 10:49

Изменено 31.03.2021 10:52 Carc

Re: лучшие практики для настроек-конфигов приложения..
Здравствуйте, MadHuman, Вы писали:

MH>Доброго всем!

MH>Коллеги, поделитесь опытом к каким практикам для организации работы с настройками в приложениях/сервисах пришли и почему..

MH>В частности интересны следующие моменты (и для затравки, привожу свой опыт)

MH>в каком формате хранить?
MH>В ini файлах — легко читать/править. большинство практических потребностей покрывает.
MH>xml/json — сложнее править, больше шансов ошибиться при ручной правке. основное преимущество — возможность большей вложенности (иерархичность) настроек,
MH>но на практике не особо ощущается т.к. в том же ini-файле вложенность вполне ок можно эмулировать за счет имен секций [system.limits]

MH>более интересный вопрос — как в приложении организована работа (чтение/хот релоад)?


  • Единый класс COptions, с открытыми member-переменными настроек (всякие bool, long\num, strings)

  • умеет писать себя и в реестр, и в ini-файл. Это спрятано внутри класс COptions. Сделано через выбор интерфейсов IWriteSettings, IReadSettings на лету. Выбор куда писать: реестр или ини-файл определяется пользователем.

    Из плюсов:
    1) Если реестр — то настройки единые для всех копий софтины на диске. Если ини — тогда у каждой копии софтины (разные версии например) у каждой свои копии настроек.
    2) Второй плюс: экспорт настроек действием пользователя суть та же запись в ini-файл через тот же самый интерфейс IWriteSettings. Разве что имя ини-файла выбирается пользователем стандартным диалогом выбора файла.
    3) Легкость создания портабельных настроек. Для портабельной версии используется запись\чтение настроек именно в\из ини-файла.

  • Для каких-то малоиспользуемых настроек (к примеру, какая-то третьеразрядная галка, в каком-то вспомогательном диалоге, в самом дальнем уголке проекта) этот класс COptions предоставляет парочку статических функций Write_Value(bool|string|num) и соответственно Read_Value(…). Но за уникальный ключ (для реестра\ини-файла) отвечает внешний код. Какое-то маловменяемое имя (ключ) для таких настроек придумать несложно. Благо это всё равно используется для малозначимых, каких-то там третьеразрядных настроек.

  • Чтение в стиле hot. При первом же обращении к такому классу COptions, он сам выполняет чтение (из того же рееестра\ини-файла).

  • Все переменные в COptions — открытые, дабы без конца не мутить геттеры\сеттеры.

  • Как только появляется более "хитропопая" логика использования какой-либо переменной, она переносится в private. И приписывается геттер\сеттер. Проект, конечно, приходится крепко пересобрать. Но компилятор сам всё отловит. Останется только пробежаться по таким ошибочным строчкам, и тупо через копи-паст заменить прямое обращение к переменной на вызовы геттеров\сеттеров.

    Пример: выручает когда чешутся ручки удалить какую-то настройку, потому как, никто ей как настройкой и не пользуется. Но "терзают смутные сомнения" ©, а пользователям оно как будет? Может кто-то всё-таки использует эту "мнительную" настройку.

    В таком случае переменная этой настройки в COptions закрывается в private, дописываются геттеры-сеттеры, и всё пересобирается. Но! Есть нюанс. Сами геттеры\сеттеры просто ни хрена не делают. Геттер всегда возвращает одну и ту же константу, сеттер — это просто пустышка.
    Что это дает: для внешнего кода всё как было, так и осталось читает\меняет настройку через геттеры\сеттеры. Логика как была, так и осталось. Но де факто то, на самом деле никакой настройки больше нет.

    Со временем, если всё тихо, и пользователям "такой поворот с рекой" прошел нормально, эти пустышки геттеры\сеттеры удаляются.

    А вот если начинается кипешь пользователей на тему "верни настройку, я все прощу", тогда просто правим пару строк в геттерах\сеттерах — возвращая логику настройки по сути. И опять просто пересобираем код, и всё готово.

    Ну, как-то так что ли…
  • Re: лучшие практики для настроек-конфигов приложения..
    Здравствуйте, MadHuman, Вы писали:

    MH>Доброго всем!

    MH>Коллеги, поделитесь опытом к каким практикам для организации работы с настройками в приложениях/сервисах пришли и почему..

    MH>В частности интересны следующие моменты (и для затравки, привожу свой опыт)

    MH>в каком формате хранить?
    MH>В ini файлах — легко читать/править. большинство практических потребностей покрывает.
    MH>xml/json — сложнее править, больше шансов ошибиться при ручной правке. основное преимущество — возможность большей вложенности (иерархичность) настроек,
    MH>но на практике не особо ощущается т.к. в том же ini-файле вложенность вполне ок можно эмулировать за счет имен секций [system.limits]

    MH>более интересный вопрос — как в приложении организована работа (чтение/хот релоад)?


  • Единый класс COptions, с открытыми member-переменными настроек (всякие bool, long\num, strings)

  • умеет писать себя и в реестр, и в ini-файл. Это спрятано внутри класс COptions. Сделано через выбор интерфейсов IWriteSettings, IReadSettings на лету. Выбор куда писать: реестр или ини-файл определяется пользователем.

    Из плюсов:
    1) Если реестр — то настройки единые для всех копий софтины на диске. Если ини — тогда у каждой копии софтины (разные версии например) у каждой свои копии настроек.
    2) Второй плюс: экспорт настроек действием пользователя суть та же запись в ini-файл через тот же самый интерфейс IWriteSettings. Разве что имя ини-файла выбирается пользователем стандартным диалогом выбора файла.
    3) Легкость создания портабельных настроек. Для портабельной версии используется запись\чтение настроек именно в\из ини-файла.

  • Для каких-то малоиспользуемых настроек (к примеру, какая-то третьеразрядная галка, в каком-то вспомогательном диалоге, в самом дальнем уголке проекта) этот класс COptions предоставляет парочку статических функций Write_Value(bool|string|num) и соответственно Read_Value(…). Но за уникальный ключ (для реестра\ини-файла) отвечает внешний код. Какое-то маловменяемое имя (ключ) для таких настроек придумать несложно. Благо это всё равно используется для малозначимых, каких-то там третьеразрядных настроек.

  • Чтение в стиле hot. При первом же обращении к такому классу COptions, он сам выполняет чтение (из того же реестра\ини-файла).

  • Все переменные в COptions — открытые, дабы без конца не мутить геттеры\сеттеры.

  • Как только появляется более "хитропопая" логика использования какой-либо переменной, она переносится в private. И приписывается геттер\сеттер. Проект, конечно, приходится крепко пересобрать. Но компилятор сам всё отловит. Останется только пробежаться по таким ошибочным строчкам, и тупо через копи-паст заменить прямое обращение к переменной на вызовы геттеров\сеттеров.

    Пример: выручает когда чешутся ручки удалить какую-то настройку, потому как, никто ей как настройкой и не пользуется. Но "терзают смутные сомнения" ©, а пользователям оно как будет? Может кто-то всё-таки использует эту "мнительную" настройку.

    В таком случае переменная этой настройки в COptions закрывается в private, дописываются геттеры-сеттеры, и всё пересобирается. Но! Есть нюанс. Сами геттеры\сеттеры просто ни хрена не делают. Геттер всегда возвращает одну и ту же константу, сеттер — это просто пустышка.
    Что это дает: для внешнего кода всё как было, так и осталось читает\меняет настройку через геттеры\сеттеры. Логика как была, так и осталось. Но де факто то, на самом деле никакой настройки больше нет.

    Со временем, если всё тихо, и пользователям "такой поворот с рекой" прошел нормально, эти пустышки геттеры\сеттеры удаляются.

    А вот если начинается кипешь пользователей на тему "верни настройку, я все прощу", тогда просто правим пару строк в геттерах\сеттерах — возвращая логику настройки по сути. И опять просто пересобираем код, и всё готово.

    Ну, как-то так что ли…