Zastanawiam się od jakiegoś czasu nad plikami konfiguracyjnymi i ich związkiem z kodem i w zależności od dnia i kierunku wiatru moje opinie wydają się zmieniać. Coraz bardziej jednak wracam do świadomości, którą po raz pierwszy miałem podczas nauki Lispa: istnieje niewielka różnica między danymi a kodem. Wydaje się to podwójnie prawdziwe w przypadku plików konfiguracyjnych. W odpowiednim świetle skrypt Perla to niewiele więcej niż plik konfiguracyjny dla Perla. Ma to zwykle dość poważne konsekwencje dla zadań, takich jak kontrola jakości i podziały pracy, takie jak to, kto powinien być odpowiedzialny za zmianę plików konfiguracyjnych.
Przejście z pliku konfiguracyjnego do pełnoprawnego języka jest generalnie powolne i wydaje się być spowodowane chęcią posiadania ogólnego systemu. Większość projektów wydaje się zaczynać od małych elementów konfiguracyjnych, takich jak miejsce zapisywania dzienników, miejsce wyszukiwania danych, nazw użytkowników i haseł itp. Ale potem zaczynają się rozwijać: funkcje zaczynają być włączane i wyłączane, czas i kolejność operacji zaczynają być kontrolowane i nieuchronnie ktoś chce zacząć dodawać do niej logikę (np. użyj 10, jeśli maszyna jest X i 15, jeśli maszyna jest Y). W pewnym momencie plik konfiguracyjny staje się językiem specyficznym dla domeny i do tego jest słabo napisany.
Teraz, gdy mam już dużo roboty, aby ustawić scenę, oto moje pytania:
- Jaki jest prawdziwy cel pliku konfiguracyjnego?
- Czy należy postarać się, aby pliki konfiguracyjne były proste?
- Kto powinien być odpowiedzialny za wprowadzanie w nich zmian (programiści, użytkownicy, administratorzy itp.)?
- Czy powinny podlegać kontroli źródła (patrz pytanie 3)?
Jak powiedziałem wcześniej, moje odpowiedzi na te pytania ciągle się zmieniają, ale teraz myślę:
- aby umożliwić nie-programistom szybką zmianę dużych fragmentów zachowania
- tak, wszystko, co nie jest gruboziarniste, powinno być zakodowane
- użytkownicy powinni być odpowiedzialni za pliki konfiguracyjne, a programiści powinni być odpowiedzialni za warstwę konfiguracji między plikami konfiguracyjnymi a kodem, która zapewnia bardziej szczegółową kontrolę nad aplikacją
- nie, ale powinna być drobniejsza warstwa środkowa
Odpowiedzi:
Bardzo ciekawe pytania!
Zwykle ograniczam moje pliki konfiguracyjne do bardzo prostego formatu „klucz = wartość”, ponieważ w pełni zgadzam się z Tobą, że pliki konfiguracyjne mogą bardzo szybko stać się pełnoprawnymi programami. Na przykład, każdy, kto kiedykolwiek próbował „skonfigurować” OpenSER, zna uczucie, o którym mówisz: to nie jest konfiguracja, to (bolesne) programowanie.
Kiedy potrzebujesz, aby Twoja aplikacja była bardzo „konfigurowalna” w sposób, którego nie możesz sobie dzisiaj wyobrazić, to naprawdę potrzebujesz systemu wtyczek . Musisz opracować swoją aplikację w taki sposób, aby ktoś inny mógł zakodować nową wtyczkę i podłączyć ją do Twojej aplikacji w przyszłości.
A więc odpowiadając na pytania:
Jaki jest prawdziwy cel pliku konfiguracyjnego?
Powiedziałbym, aby pozwolić ludziom, którzy zainstalują twoją aplikację, na modyfikowanie niektórych parametrów związanych z wdrażaniem, takich jak nazwa hosta, liczba wątków, nazwy potrzebnych wtyczek i parametry wdrażania tych wtyczek (sprawdź przykład konfiguracji FreeRadius) itp. Zdecydowanie nie jest to miejsce do wyrażania logiki biznesowej.
Czy należy postarać się, aby pliki konfiguracyjne były proste?
Zdecydowanie. Jak zasugerowałeś, „programowanie” w pliku konfiguracyjnym jest okropne. Uważam, że należy tego unikać.
Kto powinien być odpowiedzialny za wprowadzanie w nich zmian (programiści, użytkownicy, administratorzy itp.)?
Ogólnie powiedziałbym administratorów, którzy wdrażają aplikację.
Czy powinny podlegać kontroli źródła (patrz pytanie 3)?
Zazwyczaj NIE source-control pliki konfiguracyjne siebie, ale robić źródłowego kontrolę plik konfiguracyjny szablonu z wszystkich parametrów i ich wartości domyślne i komentarzy opisujących to, co robią. Na przykład, jeśli plik konfiguracyjny jest nazwany
database.conf
, zwykle kontroluję źródło pliku o nazwiedatabase.conf.template
. Teraz oczywiście mówię o tym, czym się zajmuję jako programista . Jako administrator mogę chcieć kontrolować źródła rzeczywistych ustawień, które wybrałem dla każdej instalacji. Na przykład, zarządzamy zdalnie kilkuset serwerami i musimy śledzić ich konfiguracje: zdecydowaliśmy się to zrobić z kontrolą źródła.Edytować: Chociaż uważam, że powyższe dotyczy większości aplikacji, oczywiście zawsze są wyjątki. Twoja aplikacja może na przykład umożliwiać swoim użytkownikom dynamiczne konfigurowanie złożonych reguł. Większość klientów poczty e-mail umożliwia użytkownikom definiowanie reguł zarządzania ich wiadomościami e-mail (na przykład „wszystkie wiadomości e-mail pochodzące od„ jan kowalski ”i niezawierające mnie w polu Do: powinny zostać odrzucone”). Innym przykładem jest aplikacja, która pozwala użytkownikowi zdefiniować nową złożoną ofertę handlową. Możesz również pomyśleć o aplikacjach takich jak Cognos, które pozwalają swoim użytkownikom tworzyć złożone raporty w bazie danych. Klient poczty e-mail prawdopodobnie zaoferuje użytkownikowi prosty interfejs do definiowania reguł, a to wygeneruje złożony plik konfiguracyjny (lub może nawet fragment kodu). Z drugiej strony, konfiguracja zdefiniowana przez użytkownika dla ofert handlowych może zostać zapisana w bazie danych w sposób ustrukturyzowany (ani prosta struktura klucz = wartość, ani fragment kodu). Niektóre inne aplikacje mogą nawet pozwolić użytkownikowi na programowanie w języku Python lub VB lub innym języku obsługującym automatyzację. Innymi słowy ... Twój przebieg może się różnić.
źródło
Ok. Będziesz mieć kilku użytkowników, którzy chcą naprawdę prostej konfiguracji, powinieneś im ją przekazać. W tym samym czasie będziesz mieć ciągłe żądania „Czy możesz to dodać? Jak to zrobić w pliku konfiguracyjnym?”, Nie rozumiem, dlaczego nie możesz obsługiwać obu grup.
Projekt, nad którym obecnie pracuję, używa Lua jako pliku konfiguracyjnego. Lua jest językiem skryptowym i działa całkiem dobrze w tym scenariuszu. Dostępny jest przykład naszej domyślnej konfiguracji .
Zauważysz, że są to głównie instrukcje klucz = wartość, gdzie wartość może być dowolnym typem wbudowanym Lua. Najbardziej skomplikowaną rzeczą są listy i nie są one tak naprawdę skomplikowane (to tylko kwestia składni).
Teraz czekam tylko, aż ktoś zapyta, jak ustawić port serwera na losową wartość za każdym razem, gdy go uruchomią ...
źródło
Niedawno pracowałem nad projektem i zdałem sobie sprawę, że chcę mieć warunki warunkowe w swoim pliku konfiguracyjnym - który wcześniej był po prostu dość prostym formularzem:
Nie chciałem pisać mini-języka, ponieważ jeśli nie zrobiłem tego bardzo ostrożnie, nie mogłem pozwolić sobie na elastyczność, która byłaby przydatna.
Zamiast tego zdecydowałem, że będę miał dwie formy:
Jeśli plik zaczynał się od „#!” i był wykonywalny, przeanalizowałbym wynik jego uruchomienia.
W przeciwnym razie przeczytałbym to tak, jak jest
Oznacza to, że mogę teraz pozwolić ludziom pisać „pliki konfiguracyjne”, które wyglądają tak:
W ten sposób uzyskuję moc dynamicznego pliku konfiguracyjnego, jeśli użytkownik chce z niego korzystać, oraz prostotę braku konieczności pisania własnego mini-języka.
źródło
Każdy (wystarczająco długo żyjący) schemat pliku konfiguracyjnego ostatecznie staje się językiem programowania. Ze względu na wszystkie konsekwencje, które opisujesz, mądrze jest, aby projektant plików konfiguracyjnych zdał sobie sprawę, że tworzy język programowania i odpowiednio planuje, aby nie obciążać przyszłych użytkowników złym dziedzictwem.
źródło
Mam inną filozofię dotyczącą plików konfiguracyjnych. Dane o tym, jak aplikacja powinna być uruchamiana, to nadal dane i dlatego znajdują się w magazynie danych, a nie w kodzie (plik konfiguracyjny IMO to kod). Jeśli użytkownicy końcowi muszą mieć możliwość zmiany danych, aplikacja powinna zapewniać odpowiedni interfejs.
Używam plików konfiguracyjnych tylko do wskazywania magazynów danych.
źródło
Możesz zwrócić się do teorii obliczeń, aby zdefiniować, co liczy się jako język programowania. Jeśli format twojego pliku konfiguracyjnego to Turing Complete, to rozsądnie liczy się jako język programowania. Zgodnie z tą definicją format pliku opisujący poziomy Sokoban liczy się jako język programowania (patrz tutaj ). Istnieją inne poziomy złożoności poniżej Turing Complete, które również mogą się liczyć, takie jak gramatyki regularne i automaty przesuwające w dół .
Innym sposobem spojrzenia na to jest to, że wiele plików konfiguracyjnych może tylko oznaczać dane, podczas gdy odpowiedni język programowania musi być w stanie implementować algorytmy . Na przykład JSON to format pliku konfiguracyjnego, podczas gdy ECMA Script to język programowania.
źródło
Oto moje myśli:
Aby umożliwić łatwą modyfikację zachowania aplikacji w czasie wykonywania. Mogą to być programiści lub osoby niebędące programistami, w zależności od potrzeb. Może to mieć miejsce podczas programowania, ale często postrzegam pliki konfiguracyjne jako sposób na uczynienie programu bardziej elastycznym w dowolnym momencie.
Tak. Myślę, że pliki konfiguracyjne powinny być tak proste, jak to tylko możliwe, biorąc pod uwagę ograniczenie, że możesz potrzebować różnych opcji do kontrolowania różnych zachowań środowiska wykonawczego. Preferuję grupowanie ustawień konfiguracyjnych i maksymalne ich uproszczenie.
Zależy od tego, co i dlaczego dokonywana jest zmiana. Jeśli użytkownicy mają zamiar to zmienić, należy utworzyć interfejs, który ukryje ich przed szczegółami. To samo często dotyczy ogólnie osób niebędących programistami.
Często kontroluję „domyślną” konfigurację, ale mam sposób na zastąpienie tego dla każdego systemu w czasie rzeczywistym.
Jeśli chodzi o dodanie logiki do pliku konfiguracyjnego - unikałbym tego. Myślę, że lepiej jest po prostu przełączyć plik konfiguracyjny na logikę w aplikacji. Z mojego doświadczenia wynika, że zachowanie w plikach konfiguracyjnych prowadzi do braku możliwości utrzymania i zrozumienia. Zdecydowanie wolę, aby pliki konfiguracyjne były tak proste, jak to tylko możliwe.
źródło
Zgadzam się z przesłanką tego pytania. Unikam wpadania w kłopoty, przewidując wcześnie, że to się stanie, i dlatego nigdy nie rozwijam własnego systemu konfiguracyjnego.
I zrezygnować z decyzji, którą podjąłem, lub, jeśli nie mogę, zmienić tego, aby użyć jednej z powyższych opcji, która lepiej pasuje do aplikacji.
Chodzi o to, że tak naprawdę nie ma powodu, aby używać rozwiązania konfiguracyjnego stworzonego w domu. Po pierwsze, trudniej jest Twoim użytkownikom nauczyć się nowego, specyficznego dla aplikacji formatu konfiguracji. Po drugie, korzystasz ze wszystkich wielu poprawek błędów i aktualizacji, które są dostępne bezpłatnie, gdy używasz gotowego rozwiązania. Wreszcie, pełzanie funkcji zostaje zatrzymane, ponieważ, cóż, tak naprawdę nie możesz po prostu dodać jeszcze jednej funkcji bez naprawdę gruntownego przeglądu, ponieważ system konfiguracyjny nie jest w twoich rękach.
źródło
To zależy od tego, co zgodzisz się z innymi programistami w zespole. Czy używasz plików konfiguracyjnych tak samo, jak plików konfiguracyjnych, czy też tworzysz aplikację opartą na modelu .
Objawy, że plik konfiguracyjny staje się językiem programowania:
źródło
Pliki konfiguracyjne niezmiennie stają się brzydkimi, nielogicznymi „pełnoprawnymi językami programowania”. Projektowanie dobrych języków programowania wymaga sztuki i umiejętności, a języki konfiguracji, które stały się językiem programowania, wydają się być przerażające.
Dobrym podejściem jest użycie ładnie zaprojektowanego języka, powiedzmy python lub ruby, i użycie go do stworzenia DSL dla swojej konfiguracji. W ten sposób twój język konfiguracji może pozostać prosty z pozoru, ale w rzeczywistości być pełnoprawnym językiem programowania.
źródło
Uważam, że twoje pytanie jest bardzo istotne, biorąc pod uwagę przejście do „płynnych interfejsów”. Wielu programistów „ujrzało światło dzienne” w odniesieniu do aplikacji skonfigurowanych w języku XML. Używanie XML może być bardzo rozwlekłe i trudne do poprawnej edycji (zwłaszcza jeśli nie ma schematu). Posiadanie płynnego interfejsu umożliwia programiście skonfigurowanie aplikacji w języku specyficznym dla domeny przy pomocy niektórych par klucz-wartość z pliku konfiguracyjnego zwykłego tekstu (lub być może parametrów wiersza polecenia). Ułatwia również konfigurację i konfigurację nowych instancji aplikacji do testowania lub czegokolwiek.
Oto moje odpowiedzi na Twoje pytanie:
Plik konfiguracyjny to sposób na umożliwienie użytkownikowi dostosowania zachowania programu w czasie wykonywania.
Idealnie wydaje mi się, że pliki konfiguracyjne powinny być przynajmniej uzupełnione o płynny interfejs do konfiguracji programu (jest to przydatne pod wieloma względami). Jeśli potrzebujesz pliku konfiguracyjnego, powinien on być bardzo prosty, nic poza parami klucz-wartość.
Myślę, że odpowiedź na to zależy od Twojej organizacji. Osoba wdrażająca oprogramowanie powinna odpowiadać za zapewnienie, że jest ono prawidłowo skonfigurowane.
Ukradnę tę odpowiedź od kogoś innego :) Podoba mi się pomysł przechowywania konfiguracji szablonu w kontroli źródła i modyfikowania jej na potrzeby każdego lokalnego użytkownika. Istnieje prawdopodobieństwo, że plik konfiguracyjny jednego programisty jest koszmarem innego programisty, więc najlepiej pozostawić rzeczy, które różnią się w zależności od użytkownika, poza kontrolą źródła. Posiadanie szablonu jest również dobrym sposobem, aby osoba wdrażająca aplikację (lub inni programiści) zobaczyła dokładnie, jakie wartości są prawidłowe dla pliku konfiguracyjnego.
źródło
Widziałem programy w Pythonie, w których plik konfiguracyjny jest kodem. Jeśli nie musisz robić nic specjalnego (warunkowego itp.), Nie różni się to zbytnio od innych stylów konfiguracji. np. mógłbym zrobić plik
config.py
z takimi rzeczami jak:a jedyne obciążenie dla użytkownika, w porównaniu z (powiedzmy) plikami INI, polega na tym, że muszą oni umieszczać „wokół ciągów znaków”. Bez wątpienia można zrobić to samo w innych językach tłumaczonych. Daje nieograniczoną możliwość skomplikowania pliku konfiguracyjnego, jeśli to konieczne, z ryzykiem wystraszenia użytkowników.
źródło
Tak, pliki konfiguracyjne powinny być proste. Same w sobie nie powinny zawierać „logiki” - należy traktować je jako listę wyrażeń w instrukcjach if, a nie jako całość instrukcji warunkowych.
Są po to, aby pozwolić użytkownikowi zdecydować, które z opcji zakodowanych w aplikacji powinny zostać użyte, więc nie próbuj ich komplikować, skończy się to samobójstwem - możesz w końcu napisać proste pliki konfiguracyjne aby kontrolować, jak oryginalny plik konfiguracyjny powinien być skonfigurowany inaczej!
źródło
Jednym z celów pracy „Oslo” w Microsoft jest umożliwienie (choć nie wymaganie) rozwiązania tego problemu.
Oznacza to, że odpowiednik dzisiejszych plików konfiguracyjnych może być wystarczająco bogaty, aby obsługiwać zarówno tekstową, jak i graficzną edycję ich konfiguracji. Narzędzie graficzne będzie dostarczane z „Oslo” (nazwa kodowa „Kwadrant”).
źródło
Będę przeciwieństwem i stwierdzę, że jest to język tylko wtedy, gdy zawiera więcej niż może być reprezentowane przez XML; lub gdy XML jest uważany za język.
Alternatywnie większość plików konfiguracyjnych można traktować jako klasy, ale tylko z właściwościami i bez metod. A bez metod nie sądzę, żeby to był język.
Ostatecznie „język” jest delikatną abstrakcją, ale tak, krawędzie są niejednoznaczne.
źródło
Kod naszych aplikacji staje się mniej ważny ... Jest skrypty, są różne rodzaje atrybutów, które definiują zachowanie klas, metod, argumentów metod i właściwości. Użytkownicy mogą definiować wyzwalacze bazy danych i ograniczenia bazy danych. Mogą istnieć bardzo skomplikowane pliki konfiguracyjne. Czasami użytkownik może zdefiniować arkusze stylów XSLT w celu manipulowania danymi wejściowymi i wyjściowymi, ponieważ nasze systemy muszą być otwarte (SOA). Są też rzeczy takie jak BizzTalk, które również wymagają złożonej konfiguracji. Użytkownicy mogą definiować złożone przepływy pracy.
Musimy napisać lepszy kod, aby poradzić sobie z tym złożonym środowiskiem, więc kod naszych aplikacji staje się ważniejszy ...
źródło
Jestem wielkim fanem używania programów w Pythonie jako plików konfiguracyjnych, szczególnie dla demonów. Lubię zająć się taktyką polegającą na tym, że demon całkowicie opróżnia konfigurację z wyjątkiem „portu konfiguracyjnego”. Następnie program w języku Python łączy się z demonem i przechodzi do tworzenia obiektów w demonie i łączenia ich w celu utworzenia żądanej konfiguracji. Po skonfigurowaniu wszystkiego demon można pozostawić do samodzielnego działania. Zaletą jest oczywiście to, że otrzymujesz pełnoprawny język programowania do pisania plików konfiguracyjnych, a ponieważ masz już sposób rozmawiania z demonem z innego programu, możesz go używać do debugowania i pobierania statystyk. Główną wadą jest konieczność obsługi wiadomości z innego programu w dowolnym momencie.
źródło
Plik konfiguracyjny : „Jaki jest mój cel?”
Ty : „Skonfiguruj masło”.
Plik konfiguracyjny : „Ok ...”
Plik konfiguracyjny : „Jaki jest mój cel?”
Ty : „Konfigurujesz masło”.
Plik konfiguracyjny : „O mój Boże”.
Plik konfiguracyjny nie ma „prawdziwego celu”. Wszystko, co ma sens dla Twojej aplikacji. Ogólnie rzecz biorąc, rzeczy, które różnią się (lub mogą się różnić) między maszynami i nie zmieniają się w trakcie działania aplikacji, powinny prawdopodobnie znajdować się w pliku konfiguracyjnym. Wartości domyślne, porty i adresy innych usług są doskonałymi kandydatami. Klucze i klucze również są świetnymi kandydatami, ale ze względów bezpieczeństwa powinny być obsługiwane oddzielnie od normalnej konfiguracji. Nie zgadzam się, że celem pliku konfiguracyjnego jest umożliwienie szybkich zmian. Celem powinno być zapewnienie elastyczności w konfiguracji aplikacji. Jeśli plik konfiguracyjny jest szybki łatwy sposób, aby umożliwić, że elastyczność, tym lepiej - ale powinien nie być zamierzając swoje pliki konfiguracyjne być często się zmienia.
Tak i nie. Czy powinieneś spróbować uprościć kod swojej aplikacji? Tak. Powinieneś starać się, aby wszystko, co piszesz, było proste i na temat. Nie jest bardziej skomplikowane, niż powinno. To samo dotyczy twojej konfiguracji. Jest to jednak bardzo specyficzne dla aplikacji. Zakodowanie tego, co powinno być w konfiguracji, ponieważ spowodowałoby to, że konfiguracja byłaby „zbyt skomplikowana”, to zły projekt. W rzeczywistości próba „prostoty” powoduje, że pliki konfiguracyjne stają się wielkim bałaganem. Czasami najprostszym ruchem jest modularyzacja. Dlatego twoje pliki konfiguracyjne powinny być napisane w dobrze znanym języku programowania ogólnego przeznaczenia - a nie jakimś okropnym językiem konfiguracyjnym (czytaj: wszystkie "języki konfiguracji" są do niczego ).
Ponownie, kto powinien modyfikować pliki konfiguracyjne, jest całkowicie zależny od aplikacji. Ale zgadzam się z miniquarkiem, kto wdraża aplikację, powinien być odpowiedzialny za konfigurację.
Kontrola źródła wszystko, co możesz. Kontrola źródła jest świetna. Możesz bardzo łatwo przywrócić dane i masz pełną historię wprowadzonych zmian oraz zapis, kto wprowadził te zmiany. Więc dlaczego nie?
źródło