Rozbudowane aplikacje potrzebują funkcji pozwalających je konfigurować. Jak zrobić prosty silnik zarządzania aplikacją napisaną w C++?

DRY (and others)

Zgodnie z zasadą DRY, nie powinniśmy powtarzać wielokrotnie tych samych żmudnych czynności, lecz wypracować mechanizmy pozwalające wydzielić tę czynność do narzędzia wielokrotnego użytku, tym samym automatyzując sobie pracę i skracając jej czas i redukując potrzebne na jej wykonanie zasoby. Zasadę tę można śmiało rozszerzyć - nie powinniśmy powtarzać także przygotowanych przez innych rozwiązań, zwłaszcza gdy działają, są udostępnione za darmo i są odpowiadającej nam jakości (no chyba że w celach nauki). Podsumowując, warto się rozejrzeć za gotowymi narzędziami do zarządzania konfiguracją aplikacji napisanych w C++.

SettingsParser

SettingsParser jest prostą biblioteką napisaną w C++, nieposiadającą zewnętrznych zależności, udostępnioną za darmo na licencji zlib, udostępnioną na GitHubie przez programistę Foaly.

Biblioteka SettingsParser pozwala na odczyt i zapis konfiguracji w formacie przypominającym stary i lubiany format ini (ale bez wsparcia dla sekcji). Mamy tu więc proste, jednolinijkowe konstrukcje klucz = wartość. To jednak wystarczy nam już aby skonfigurować prostą aplikację.

SettingsParser settings;
if (!settings.loadFromFile("dds.ini")) {
    return -1;
}

Ponadto, dzięki wbudowanym metodom szablonowym, biblioteka ta zadba o konwersję odczytanych z pliku wartości do typu zmiennej której wartość tę chcemy przypisać (w przykładzie DrugsHandler dziedziczy po Handler):

Handler::Handler(SettingsParser settings) : settings(settings) {}

SettingsParser Handler::getSettings() {
    return settings;
}

void DrugsHandler::onRequest(const Net::Rest::Request& request, Net::Http::ResponseWriter response) {
    
    std::string files_path;
    
    getSettings().get("files_path", files_path);
    
    if (!files_path.empty()) {
        
        std::ostringstream s;
        s << files_path << "/drugs.json";
        
        Http::serveFile(response, s.str().c_str(), MIME(Application, Json));
            
    } else {
        response.send(Http::Code::Internal_Server_Error);
    }
    
}

Biblioteka SettingsParser może być łatwo zaadoptowana do każdego projektu, a dzięki braku zależności łatwo wstrzyknieta do kodu i wkorzystana stosując techniki DI.

Pokazane w tym wpisie przykłady są zaczerpnięte z aplikacji DDS.