Čau Habr!
V tomto článku začneme příběh o tom, jak to uvnitř funguje platforma "1C:Enterprise 8" a jaké technologie se při jeho vývoji používají.
Proč si myslíme, že je to zajímavé? Za prvé proto, že platforma 1C:Enterprise 8 je velká (více než 10 milionů řádků kódu) aplikace v C++ (klient, server atd.), JavaScript (webový klient) a v poslední době i A Jáva. Velké projekty mohou být zajímavé přinejmenším svým rozsahem, protože problémy, které jsou v malé kódové základně neviditelné, se v takových projektech objevují v plné síle. Za druhé, „1C:Enterprise“ je replikovatelný, „krabicový“ produkt a na Habré je jen velmi málo článků o takovém vývoji. Vždy je také zajímavé vědět, jak se žije v jiných týmech a společnostech.
Pojďme tedy začít. V tomto článku poskytneme přehled některých technologií, které se v platformě používají, a nastíníme krajinu, aniž bychom se hluboce ponořili do implementace. Vskutku, pro mnoho mechanismů by podrobný příběh vyžadoval samostatný článek a pro některé celou knihu!
Pro začátek stojí za to rozhodnout se o základních věcech – co je platforma 1C:Enterprise a z jakých komponent se skládá. Odpověď na tuto otázku není tak jednoduchá, protože pojem „platforma“ (pro stručnost tomu budeme říkat) označuje prostředek pro vývoj podnikových aplikací, runtime prostředí a administračních nástrojů. Lze zhruba rozlišit následující složky:
serverový cluster
„tenký“ klient schopný připojení k serveru přes http a svůj vlastní binární protokol
klient pro práci ve dvouvrstvé architektuře s databází umístěnou na pevném disku nebo síťové složce
webový klient
nástroje pro správu aplikačního serveru
vývojové prostředí (známé jako Configurator)
runtime prostředí pro iOS, Android a Windows Phone (mobilní platforma 1C)
Všechny tyto části, s výjimkou webového klienta, jsou napsány v C++. Navíc je tu nedávno oznámená Konfigurátor nové generace, napsaný v Javě.
Nativní aplikace
C++03 se používá k vývoji nativních aplikací. Pro Windows se jako kompilátor používá Microsoft Visual C++ 12 (profil kompatibilní s Windows XP) a pro Linux a Android - gcc 4.8, pro iOS - clang 5.0. Použitá standardní knihovna je stejná pro všechny operační systémy a kompilátory – STLPort. Toto řešení snižuje pravděpodobnost chyb specifických pro implementaci STL. V současné době plánujeme migraci na implementaci STL dodávanou s CLangem, protože STLPort byl ukončen a není kompatibilní s režimem Gcc s povoleným C++11.
Základ kódu serveru je z 99 % společný, klientský - 95 %. Navíc i mobilní platforma používá stejný kód C++ jako ta „velká“, i když procento sjednocení je tam o něco nižší.
Stejně jako většina uživatelů C++ netvrdíme, že využíváme 100 % možností jazyka a jeho knihoven. Boost tedy prakticky nepoužíváme a jednou z jazykových vlastností je dynamické přetypování. Zároveň aktivně využíváme:
Použitím vícenásobné dědičnosti rozhraní (zcela abstraktní třídy) se stává možným model komponenty, o kterém bude pojednáno níže.
Komponenty
Pro zajištění modularity je veškerá funkčnost rozdělena do komponent, kterými jsou dynamické knihovny (*.dll pro Windows, *.so pro Linux). Celkem existuje více než sto padesát komponent, zde jsou popisy některých z nich:
backend
Obsahuje modul metadat platformy
accnt
Objekty, které vývojáři aplikací používají k vytváření účetních záznamů (účtové diagramy a účetní registry)
bsl
Vestavěný jazyk pro provádění motoru
nuke
Vlastní implementace alokátoru paměti
dbeng8
Databázový stroj souborů. Jednoduchý databázový stroj souborového serveru založený na ISAM, který také obsahuje jednoduchý SQL procesor
wbase
Obsahuje základní třídy a funkce pro implementaci uživatelského rozhraní Windows – třídy oken, GDI přístup atd.
Rozdělení na více komponent je užitečné z několika hledisek:
Oddělení podporuje lepší design, zejména lepší izolaci kódu
Ze sady komponentů můžete flexibilně sestavit různé možnosti dodání:
Například instalace tenkého klienta bude obsahovat wbase, ale nebude mít backend
ale na serveru wbase to naopak nebude
obě možnosti budou samozřejmě obsahovat nuke a bsl
Všechny součásti potřebné pro tuto možnost spuštění se načtou při spuštění programu. To je nezbytné zejména pro registraci tříd SCOM, o kterých bude pojednáno níže.
SCOM
Pro rozklad na nižší úrovni se používá systém SCOM, knihovna ideologií podobná ATL. Pro ty, kteří s ATL nepracovali, uvádíme stručně hlavní možnosti a funkce.
Pro speciálně navrženou třídu SCOM:
Poskytuje tovární metody, které vám umožňují vytvořit třídu z jiné komponenty, která zná pouze její název (bez odhalení implementace)
Poskytuje infrastrukturu inteligentních ukazatelů pro počítání referencí. Životnost třídy SCOM není nutné monitorovat ručně
Umožňuje vám zjistit, zda objekt implementuje konkrétní rozhraní, a automaticky převést ukazatel na objekt na ukazatel na rozhraní
Vytvořte objekt služby, který je vždy přístupný prostřednictvím metody get_service atd.
Můžete například popsat třídu pro čtení JSON (například JSONStreamReader) v komponentě json.dll.
Třídy a instance mohou být vytvořeny z jiných komponent; musí být zaregistrovány v počítači SCOM:
SCOM_CLASS_ENTRY(JSONStreamReader)
Toto makro bude popisovat speciální třídu statického záznamníku, jejíž konstruktor bude volán při načtení komponenty do paměti.
Poté můžete vytvořit jeho instanci v jiné komponentě:
Pro podporu služeb nabízí SCOM další, poměrně složitou infrastrukturu. Ústředním prvkem je koncept procesu SCOM, který slouží jako kontejner pro spouštění služeb (tj. hraje roli Service Locator) a obsahuje také vazbu na lokalizované zdroje. Proces SCOM je vázán na vlákno OS. Díky tomu můžete uvnitř aplikace přijímat služby jako:
SCOM_Process* process = core::current_process();
if (process)
return get_service<IMyService>(process);
Navíc přepínáním logických (SCOM) procesů vázaných na vlákno můžete získat aplikace, které jsou prakticky nezávislé z pohledu informačního prostoru, běžící v rámci stejného vlákna. Náš tenký klient takto pracuje se souborovou databází – uvnitř jednoho procesu OS jsou dva procesy SCOM, jeden spojený s klientem a druhý se serverem. Tento přístup nám umožňuje sjednotit psaní kódu, který bude fungovat jak na lokální databázi souborů, tak ve „skutečné“ verzi klient-server. Cena za takovou uniformitu je sice režijní, ale praxe ukazuje, že se to vyplatí.
Na základě modelu komponent SCOM je implementována jak obchodní logika, tak část rozhraní 1C: Enterprise.
Uživatelské rozhraní
Mimochodem, o rozhraních. Nepoužíváme standardní ovládací prvky Windows, naše ovládací prvky jsou implementovány přímo na Windows API. Pro verzi pro Linux byla vytvořena vrstva, která funguje prostřednictvím knihovny wxWidgets.
Knihovna ovládacích prvků nezávisí na jiných částech 1C:Enterprise a používáme ji v několika dalších malých interních utilitách.
V průběhu let vývoje 1C:Enterprise se vzhled ovládacích prvků změnil, ale k vážné změně principů došlo pouze jednou, v roce 2009, s vydáním verze 8.2 a příchodem „spravovaných formulářů“. Kromě změny vzhledu se zásadně změnil princip rozvržení formuláře - došlo k zamítnutí rozmístění prvků pixel po pixelu ve prospěch flow-layout prvků. V novém modelu navíc ovládací prvky nepracují přímo s doménovými objekty, ale se speciálními DTO (Objekty přenosu dat).
Tyto změny umožnily vytvořit webového klienta 1C:Enterprise, který replikuje logiku C++ ovládacích prvků JavaScriptu. Snažíme se zachovat funkční ekvivalenci mezi tenkými a webovými klienty. V případech, kdy to není možné, například kvůli omezením dostupného JavaScript API (například možnost práce se soubory je velmi omezená), často implementujeme potřebnou funkcionalitu pomocí rozšíření prohlížeče napsaných v C++. V současné době podporujeme Internet Explorer a Microsoft Edge (Windows), Google Chrome (Windows), Firefox (Windows a Linux) a Safari (MacOS).
Technologie řízených formulářů se navíc používá k vytvoření rozhraní pro mobilní aplikace na platformě 1C. Na mobilních zařízeních je vykreslování ovládacích prvků implementováno pomocí technologií nativních pro operační systém, ale pro logiku rozvržení formuláře a odezvu rozhraní se používá stejný kód jako ve „velké“ platformě 1C:Enterprise.
1C rozhraní v OS Linux
1C rozhraní na mobilním zařízení
1C rozhraní na jiných platformách 1C rozhraní v OS Windows
Rozhraní 1C - webový klient
open source
I když nepoužíváme standardní knihovny pro vývojáře C++ pod Windows (MFC, ovládací prvky z WinAPI), nepíšeme všechny komponenty sami. Knihovna již byla zmíněna wxWidgetsa také používáme:
Seznam pokračuje.
Navíc používáme vysoce upravenou verzi Test Google и Google Mock při vývoji jednotkových testů.
Knihovny vyžadovaly přizpůsobení, aby byly kompatibilní s modelem organizace komponent SCOM.
Díky rozšíření 1C je platforma vynikajícím testem síly pro knihovny v ní používané. Řada uživatelů a scénářů rychle odhalí chyby i v těch nejvzácněji používaných oblastech kódu. Sami je opravujeme a snažíme se je vrátit autorům knihovny. Prožitek interakce se ukazuje být velmi odlišný.
Vývojáři kučera и libetpan reagovat rychle na žádosti o stažení, ale například záplata v OpenSSL Nikdy se nám to nepodařilo vrátit.
Závěr
V článku jsme se dotkli několika hlavních aspektů vývoje platformy 1C: Enterprise. V omezeném rozsahu článku jsme se dotkli jen některých zajímavých, podle nás, aspektů.
Obecný popis různých mechanismů platformy lze nalézt zde.
Jaká témata by vás v budoucích článcích zajímala?
Jak je implementována mobilní platforma 1C?
Popis vnitřní struktury webového klienta?
Nebo vás možná zajímá proces výběru funkcí pro nové verze, vývoj a testování?