Re: Modulární aplikace

2010-09-06 Tema obsahu David Mach

 Ahoj,

porušení normální formy databáze by nemělo být dogma - už kolikrát jsem 
musel volit nutné zlo v podobě redundance dat místo toho, abych omezoval 
uživatele zbytečně pomalou službou. Každopádně díky za moc cenné 
zkušenosti a dobré vodítko pro naši další práci!


David Mach


Dne 2.9.2010 7:29, Ing. Jan Novotný napsal(a):

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ř. ListData 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 m...@alis.cz mailto:m...@alis.cz

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




Re: Modulární aplikace

2010-09-02 Tema obsahu Tomas Studva
Zdravim,
my pouzivame tiez myslienku cislo jedna, teda dotazy vo forme in
obmedzeni. Tie in obmedzenia, kym sa nejedna o tisicky idciek su uplne
vpohode.

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. 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.

Ale tym ze modul ma vsetky query u seba, vznika aj duplicita niektorych
dotazov, no nie je toho vela.

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.

2010/9/2 Ing. Jan Novotný novotn...@gmail.com

 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ř. ListData
 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 m...@alis.cz

  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 

Re: Modulární aplikace

2010-09-02 Tema obsahu Oto Buchta
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 tstu...@gmail.com:
 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ý novotn...@gmail.com

 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ř. ListData
 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 

Re: Modulární aplikace

2010-09-02 Tema obsahu Tomas Studva
Mate pravdu, no upozornim este na porovnanie join vs in z pohladu 
performancie.


Potencionalny problem in dotazov moze byt, ak by sa databaza rozhodla 
prechadzat tabulku sekvencne namiesto pouzitia indexu. Ten index tam 
urcite je, kedze sa jedna o foreign key. Popravde ale ocakavam, ze na 
sekvencne citanie sa prejde iba ak rozsah ocakavaneho vysledku bude 
velky (skoro cela tabulka) a teda performancia bude vychadzat narovnako.


Na Vasom mieste by som spravil test na databaze, ktoru budete pouzivat s 
nejakymi rozumne velkymi tabulkami s nejakym beznym query. Staci to 
spravit z konzoly, netreba z aplikacie.


Tomas Studva

Oto Buchta  wrote / napísal(a):

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 tstu...@gmail.com:
  

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ý novotn...@gmail.com


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ř. ListData
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, 

Modulární aplikace

2010-09-01 Tema obsahu David Mach

 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



Re: Modulární aplikace

2010-09-01 Tema obsahu Ing . Jan Novotný
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ř. ListData
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 m...@alis.cz

  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