Jak należy zarządzać stałymi w wielu językach?

13

Mam sytuację, w której obsługuję funkcjonalnie tę samą bibliotekę w wielu językach. Często istnieją stałe, które muszą być dzielone między nimi (na przykład klucze nazwy pola Json lub kody błędów).

Obecnie robię to poprzez kod definiujący stałe w każdym języku.

Problem dotyczy konserwacji. Jeśli dodam nowy kod błędu, muszę zaktualizować go ręcznie w każdej bibliotece. Chociaż jest to w porządku dla niektórych, staje się nudne, jeśli powiem 5 aktualizacji SDK. Byłoby miło mieć dla nich jedno źródło prawdy.

Myślałem o jakimś pliku konfiguracyjnym, ale musi on zostać zawarty w każdym wdrożonym pakiecie, co zwiększa złożoność naszego procesu kompilacji / wydania.

Czy istnieje lepszy sposób obsługi utrzymywania stałych, które są współużytkowane przez wiele języków?

kraina krańca
źródło
Twoje podejście jest w porządku, krańcu. Próbowałem znaleźć lepsze rozwiązanie redefinicji, ponieważ wiele klientów używa interfejsów API, które programuję, i tak naprawdę nie ma eleganckiego rozwiązania. Ciągła redefinicja jest nadal najprostsza.
Andy,
5
@DavidPacker nie nie nie nie, powinieneś mieć naprawdę eleganckie rozwiązanie dla mnie. Nie mów mi, że to jest najlepsze! :-)
Enderland
1
Kwestionowałem moje wybory, ale potem zdałem sobie sprawę, że stałe mają być stałe. Są przewidywalne, ponieważ są stałe. Przechowując je w formacie JSON lub innym ogólnie przetwarzalnym formacie, nie są już tak naprawdę stałymi. Typowym przykładem w moim procesie pracy jest obiekt powiadomienia zawierający typeatrybut służący do identyfikacji struktury podczas przesyłania jej przez drut. Dzięki temu klienci mobilni definiują tylko stałe (typy), które rozumieją w danym momencie i ignorują nieznane typy. Definicja dynamiczna spowodowałaby wiele problemów.
Andy,
Potrzebujesz tabeli tabel odwzorowujących rzędy stałych z tabel języków.
Johnny

Odpowiedzi:

10

Chociaż myślę, że twoje obecne podejście jest prawdopodobnie najprostsze i najprostsze, oto kilka alternatywnych pomysłów:

  • Wyodrębnij swoje stałe (i być może modele) do innego pakietu, który jest kompilowany krzyżowo na wszystkie języki. Być może będziesz w stanie skompilować całą bibliotekę, ale może to wiązać się z poważnymi problemami. Po prostu stałe kompilacji krzyżowej powinny być wystarczająco proste, aby nie było tylu problemów. Możesz opublikować swój pakiet stałych i polegać na nim w bibliotekach specyficznych dla języka. Haxe prawdopodobnie to potrafi. Takie podejście jest dobre, ponieważ nadal będziesz mieć sprawdzanie czasu kompilacji (dla skompilowanych języków)
  • Zapisz konfigurację w centralnej usłudze. Na przykład usługi WWW mydła mają język opisu usługi sieci Web (WSDL), a usługi REST mają język opisu aplikacji sieci Web (WADL), który opisuje operacje i komunikaty usługi. Istnieją również ogólne usługi konfiguracji scentralizowanej, takie jak Spring Cloud Config
  • Plik konfiguracyjny. Wiem, że już to zasugerowałeś, ale nie sądzę, że musi to bardzo skomplikować proces kompilacji / wydania. Umieść plik konfiguracyjny w osobnym projekcie kompilacji (gdzie możesz go zaktualizować). Opublikuj projekt we wszystkich repozytoriach pakietów specyficznych dla języka (Maven, Nuget, NPM itp.), A następnie w bibliotekach specyficznych dla języka możesz polegać na pakiecie. Nie powinno to być bardziej skomplikowane niż posiadanie dodatkowego projektu w potoku kompilacji.
  • Jak sugeruje RubberDuck, generowanie kodu jest dobrą alternatywą dla kompilacji krzyżowej. Możesz generować stałe definicje dla każdego języka, używając wspólnej konfiguracji.
Samuel
źródło
5
Generowanie kodu @RubberDuck brzmi interesująco (szczególnie w jednym z moich stycznych przypadków użycia, które i tak już wymagają generatora kodu).
Enderland
3

Świetne pytanie! Mam dokładnie ten sam problem; moje stałe są w gruncie rzeczy: jakie języki są obsługiwane w moich aplikacjach oraz dodatkowe informacje o tych językach, ponieważ dotyczą one funkcji w aplikacji.

Niestety, najlepszą rzeczą, jaką znalazłem (jak masz), jest po prostu przedefiniowanie stałych dla każdego języka, tak jak obecnie (wiem, że zdecydowanie chciałeś to usłyszeć ).

Oczywiście wydaje się to złe, ponieważ jest przeciwieństwem OSUSZANIA ( MOKRE? ). Jednak stałe powinny zmieniać się tak rzadko, że 5–10 minut ponownego ich zdefiniowania dla każdego języka tak naprawdę mi nie przeszkadza. Na koniec drobne problemy z jakimś „eleganckim” rozwiązaniem, takim jak współdzielona konfiguracja lub generowanie kodu, mogą zająć godziny lub dni, więc co naprawdę zyskujesz? Zwiększona złożoność z ryzykiem błędu, który może wymagać dodatkowego wysiłku, aby to naprawić, nie jest czymś, z czym chcę sobie poradzić.

Ponadto, jeśli twoja aplikacja ma tak wiele stałych, że redefiniowanie ich dla języka podczas ich dodawania lub zmieniania zajmuje dużo czasu, możesz po prostu mieć bardziej znaczący zapach kodu, aby sobie z tym poradzić, i wtedy możesz chcieć zmienić na coś bardziej złożonego.

Krótko mówiąc, redefinicja ich dla każdego języka była moim najlepszym rozwiązaniem, a ja jeszcze nie wymyśliłem nic więcej SUCHEGO, które nie miałoby większego ryzyka niż chciałbym sobie poradzić.

Jedną z rzeczy, na pewno zrobić, chociaż, aby upewnić się, że stałe są dobrze udokumentowane w uogólnionej (i języka agnostyk) sposób (mamy firmy documentarion repo ze specyfikacją, różne docs „deski kreślarskiej” Dokumenty itd gdzie trzymamy ten dokument). Upewnij się także, że masz mechanizm (mechanizmy) w celu synchronizacji ich definicji. Jest to tak samo duży problem z podejściem do powielania, jak ty, z wyjątkiem niewielkiego stresu psychicznego wynikającego z celowego powielania kodu. Ale w końcu twoje ciągłe zmiany powinny być bardzo celowe i rzadkie , więc kwestie synchroniczności powinny być zasadniczo zerowe.


Powinienem również wspomnieć, że przez lata widziałem wielojęzyczne porty różnych bibliotek (zbyt zmęczone, aby pamiętać, jakie są w tej chwili) napisane przez tę samą grupę, które niezmiennie mają stałe zdefiniowane w samych językach. Brak wspólnej konfiguracji, brak generowania kodu (z wyjątkiem bibliotek klienta Google API ... ale daj spokój, Google ma zasoby, aby pozwolić sobie na taką złożoność). Więc myślę, że uderzyliśmy w ten mur. Może ktoś w końcu wymyśli bibliotekę, aby poradzić sobie z tym problemem;)

Chris Cirefice
źródło
0

Mam nadzieję, że rdzeń twojej biblioteki jest napisany w jednym języku, a inne biblioteki używają FFI ( https://en.wikipedia.org/wiki/Foreign_function_interface ) do wywoływania biblioteki podstawowej. Dałoby to centralną lokalizację do udostępnienia interfejsu API do publikowania stałych i definicji. W ten sposób wszystko jest zamknięte w bibliotece. Wspominam o tym, ponieważ wydaje się, że nie jest to uwzględnione w odpowiedzi Samuela.

Myślę, że to naprawdę zależy od tego, jak duża jest twoja baza użytkowników. Czy są w stanie obsłużyć przekazywanie innego pliku konfiguracyjnego? Czy są w stanie skonfigurować nową usługę? Dla zdecydowanej większości wspieranych przeze mnie użytkowników chciałbym, aby wszystko było samowystarczalne - w ten sposób użytkownicy nie musieliby o tym myśleć.

Robert Baron
źródło
1
Hopefully, the core of you library is written in one language, and the other libraries use FFI Niestety mamy biblioteki zarówno dla klienta WWW, jak i kodu serwera (w wielu językach), więc ... ściągnięcie go nie byłoby trywialne (i prawdopodobnie luka w zabezpieczeniach, gdybyśmy mogli zacząć od aplikacji internetowej).
Enderland
Sugerowałbym, abyś poprawił swoje bezpieczeństwo, ponieważ nigdy nie ufałbym moim użytkownikom na tyle, aby zachować poufność plików konfiguracyjnych.
Robert Baron,
Jak wdrażasz aplikacje internetowe, które obsługują kody błędów? Lub nazwy pól Json? Jestem zdezorientowany tym, co według mnie robię, jest kwestią bezpieczeństwa. Uruchamianie dowolnego kodu na maszynie mojego klienta jest absolutnie kwestią bezpieczeństwa, dlatego wydaje się, że nie można go parsować z serwera, chyba że coś mi umknie.
Enderland
Pracowałem w firmach, których podstawą bezpieczeństwa były generatory liczb losowych w stylu DOS i wartości początkowe przechowywane jako stałe. Zazwyczaj były one naprawiane bardzo szybko po ich wskazaniu. Jeśli jednak przekażesz wartość początkową światu, oddasz klucz królestwu. Ponieważ twoje oprogramowanie wydaje się być oparte głównie na sieci, zachowaj konfigurację w obiekcie JSON i pozwól, aby każdy język analizował to samo udostępniony plik.
Robert Baron,
Nazwy pól JSON prawdopodobnie nie muszą i nie powinny być stałe. Jakie byłyby szanse na zmianę tych nazw pól, ale nie zmienia się nazwy samej stałej? Prawdopodobnie bardziej prawdopodobne jest skorzystanie z generowania kodu w celu uzyskania dostępu do wpisów lub używania języka wyrażeń, takiego jak ObjectPath.
Lie Ryan,