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

Odpovedet emailem