Při návrhu modulární architektury je třeba brát na zřetel jiná možná použití dat z konkrétního modulu a umožnit zásuvné či rozšiřující submoduly do střev každého modulu. Jestli se použije vzor Listener, Observer a nebo eLISPové hooky je celkem buřt. Potom není nutné si tolik hrát s API, jenom nechat data uvnitř modulu bezpečně (myšleno odolně proti nekonzistencím dat) a správně (dva klíčové termíny Hrubozrnný a Volná vazba) protékat přes ony pluginy. Není ale potřeba se nějak dramaticky zaobírat bezpečností (myšleno přístupovými právy), neboť každý modul bude mít VŽDY možnost sáhnout si do DB ;-)
2010/9/2 Tomas Studva <[email protected]>: > Ale mame aj vinimku, mame totiz modul, ktory potrebuje citat udaje z mnohych > modulov naraz a ma vselijake svoje obmedzenia. Konkretne tento modul > exportuje data do ineho systemu a bol navrhnuty genericky. Toto je typický kámen úrazu návrhu modulárních systémů. Generický modul může přímo záviset na zase jen na generických modulech. Pokud chcete v generickém modulu volat něco z negenerického modulu, musíte použít nějaký metajazyk, kterým se deklarativně (typicky pomocí konfigurace) na něj či do něj dostanete. > S pomocou malej > konfiguracie sa da rozsirit export, niekedy vsak to nejde, lebo su tam > nejake podmienky, takze sa napise sql. Exportuju sa cele siete objektov. > Ak by to malo byt modularne, tak kazdy modul by mal exportovat svoje data, > svoju siet. No to by chcelo ovela viacej premysleny navrch, kedze > exportovane udaje nie su cela DB, ale cielom je exportovat mininum dat a dba > sa na performanciu, robia sa teda aj joiny medzi modulmi. Cize kedze tento > Export robi iba citanie, tak ma dovolene sahat do lubolnej tabulky. Ano, SQL se typicky jako metajazyk pro přístp do negenerických modulů používá a pak zde opravdu není problém. Typické nasazení je právě pro statistiky. Exporty bych se snažil řešil jinak a ideálně via pes Partes až na konec kompletace. Export miliónů záznamů se asi nebude dělat každou minutu a každou minutu se nebude dělat export miliónů záznamů, takže tím pádem JOINy určitě oželím. > Ale tym ze modul ma vsetky query u seba, vznika aj duplicita niektorych > dotazov, no nie je toho vela. V tomto problém nevidím. Implementátor při konfiguraci ví, jaké verze negenerických modulů používá a může tedy separátně nastavit dotazy. > Zaver z tohoto prikladu znie, ze moze nastat pripad, ked by sa implentacia > stazila resp. aj znizila performancia pri dodrzani modularneho dizajnu, ak > by sa dobre nepremyslel dizajn. Tak toto je téměř tautologie ;-) > > 2010/9/2 Ing. Jan Novotný <[email protected]> >> >> Ahoj, >> my jedeme na modulárním systému asi 2 roky (s tím rozdílem, že nemáme >> OSGI, ale jen zřetězené aplikační konexty Springu na stejné classpath - >> nicméně už to k zavedení modulárnosti stačí). Řešili jsme stejný problém a >> obávám se, že neexistuje ideální řešení. Základní pravidlo spočívá ve >> správném "řezu" modulů - každý by měl mít jednoznačnou odpovědnost a funkci. >> Moduly by se měly vzájemně doplňovat spíš než ve funkcionalitách překrývat. >> Prostě příliš malé moduly nejsou dobré, protože mají potom mnoho závislostí >> ven, velké moduly také nejsou dobré, protože se tím zase snižuje jejich >> použitelnost. Na správném řezu funkcionalitou prostě záleží hodně. >> Pokud by jeden modul sahal do dat jiného modulu přímo a nikoliv přes >> jeho API povede toto porušení zapouzdřenosti k: svázanosti (couplingu) >> těchto dvou modulů, zhoršení testovatelnosti, problém se samostatným >> rozvojem modulů (vždy se na ně bude muset pohlížet jako na nějaký provázaný >> celek). >> My jsme došli ke dvěma možným technikám v těchto případech (naštěstí >> těch případů není zase až tak moc). >> 1) obětování výkonu - tj. každý modul udržuje pouze svá data a pokud z >> nějakého důvodu potřebuje vrátit či pracovat s daty jiného modulu, jde přes >> jeho API - tím se ale samozřejmě nedá využít JOINů a platíme výkonem. Tyto >> mezimodulové "dotazy" se alespoň snažíme optimalizovat na metodách API tím, >> že tam máme metody pro hromadné načítání dat - např. List<Data> >> getDataById(Integer... id), která může všechna potřebná data načít >> jednorázově přes WHERE id in (...) >> 2) porušením normální formy db - kromě přímého volání mezi moduly na >> úrovni API máme ještě jednu formu komunikace postavenou na "observer >> patternu", která vychází ze Springu, tj. moduly v důležitých okamžicích své >> funkcionality publikují tzv. eventy do systému, na které pak mohou reagovat >> listenery v jiných modulech. Tímto způsobem je možné distribuovat některá >> důležitá (i agregovaná) data do zbytku systému. Uvedu příklad - máme tzv. >> hodnotící modul, který umožňuje hodnotit libovolný obsah kdekoliv (např. ve >> formě hvězdiček na nějaké škále), tento modul samozřejmě o obsahu samotném >> nic neví - naopak jiný modul, který spravuje daný obsah (třeba články) chce >> při vracení článku vracet aktuální hodnotu průměrného hodnocení. Hodnotící >> modul vždy po přepočtení aktuálního hodnotícího čísla po daný obsah vyhodí >> událost do systému, na kterou může kterýkoliv jiný modul naslouchat. Modul >> starající se o články tuto událost odchytí a k článku si uloží dodatečný >> údaj o aktuálním hodnocení (již vypočtený, hotový k zobrazení). Tímto >> způsobem je porušena normální forma - jeden údaj je v DB uložen 2x, nicméně >> data jsou potom již hezky po ruce (bez výkonnostní penalizace) a nedochází k >> narušení zapouzdřenosti modulů - jeden může bez problému fungovat bez >> druhého, pokud běží oba - spolupracují. >> Pokud existuje ještě nějaký jiný způsob komunikace rád se jej dozvím. >> Jak říkám, ani jedna z výše uvedených praktik není úplně ideální, ale na nic >> lepšího jsme za ty roky nepřišli :(. >> Honza >> -- >> -------------------------------------------------------------- >> Ing. Jan Novotný >> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ >> http://blog.novoj.net >> Myšlenky dne otce Fura >> -------------------------------------------------------------- >> >> 2010/9/1 David Mach <[email protected]> >>> >>> Zdravím všechny! >>> >>> V naší firmě jsme doposud vyvíjeli klasické aplikace na jedné classpath >>> (typu "vidím vše, volám vše, využívám vše", čili občas pěkná prasárna). Nyní >>> vyvíjíme novou modulární aplikaci postavenou na OSGi, přičemž naše původní >>> vize byla ta, že jednotlivé moduly mezi sebou budou komunikovat výhradně >>> prostřednictvím API. To by ale například znamenalo, že pro získání dat z >>> modulu A (která potřebuji pro SQL dotaz v modulu B) budu muset nejprve volat >>> nějakou metodu z API modulu A, získat ta data a teprve posléze budu moci >>> složit SQL dotaz v modulu B. Z této představy ovšem vstávají některým >>> kolegům hrůzou vlasy na hlavě a horují pro to, abychom se drželi klasické >>> cesty, kdy data z tabulek náležejících k modulu A budeme získávat pomocí >>> JOINů. >>> >>> Chci se tedy zeptat přítomných zkušenějších vývojářů na to, zda je >>> původní vize správná a také na zkušenosti z implementace. Zajímá mě také >>> rozdíl ve výkonu aplikace při použití API vs JOIN... >>> >>> Vřelé díky předem! >>> >>> David Mach >>> >> > > -- Oto 'tapik' Buchta, [email protected], http://tapikuv.blogspot.com
