Blog nejen o programování. Hlavním tématem jsou technologie, jako je Javascript, Typescript, React či GraphQL. Občas zabrousím i soft skills oblastí, díky tomu, že se dostanu do role team leadera či školitele. Dále jsem zakladatelem společnosti: https://apitree.cz
úterý 28. srpna 2007
pátek 10. srpna 2007
Aplikace nezávislá na databázovém systému
V poslední době se dost rozrůstá názor, že aplikace by měly být psány tak, aby byly co nejvíce nezávislé na použitém DBMS. Osobně tento názor zastávám i já.
Důvodů je několik:
Jak už to tak bývá, tak úspěch projektu je závislý od prvotní analýzy. Nechtějme tedy vše řešit hned od počátku. Jistě je bezpečnější si nechat otevřená zadní vrátka pro dané změny, které by mohly mít fatální následky.
Kompromis
Bohužel, nežijeme v ideálním světě, kde by vše bylo nalinkované tak, jak bychom si přáli. Uvedu jeden příklad, který mě přesvědčil o tom, že vytvořit aplikaci, která by byla skutečně nezávislá na DBMS je nemožné.
Pro načítání dat z jiných zdrojů, jsem použil Timer metody z EJB3, které mají tu vlastnost, že jsem schopný vytvořit si vlastní plánování plnění. Na persistenci jsem použil JPA. Když jsem zjistil, že JPA má možnost přiřadit listener na danou entitu, hned jsem si tuto vlastnost spojil s tím, že nebudu muset psát žádné triggery a hezky půjdu touto cestou.
To jsem si ovšem neuvědomil, že při dávkovém zpracování je JPA a EntityManager natolik náročný způsob, že jsem byl nucen přejít na nízkoúrovňové JDBC. Výhodou samozřejmě bylo extrémní zrychlení, ale nevýhodou, že daný Listener je v podstatě k ničemu. Ve finále jsem byl nucen napsat trigger a tím utnout možnost, že aplikační logika se postará o vše potřebné.
Vše není tak černé
I když jsem opustil snadnou přenostitelnost, stále mi zůstává možnost psát tu aplikaci tak, aby byl doménový model to hlavní a já byl co nejvíce odstíněn od DBMS. Přece jen, toho dávkového spracování zase není tolik, aby se to nedalo kdykoli změnit.
Používám 2 základní zdroje: MySQL a Oracle. Při klasickém přístupu jsou si obě databáze velice podobné. Je zde ovšem několik rozdílů, které jsou dost zásadní. Opět uvedu příklad, který toto vystihuje:
Chci nějaký základní reportovací nástroj, který bude pracovat tak, že uživatel napíše SQL dotaz, systém ho zpracuje a vrátí tabulku. Tabulku, která bude obsahovat možnost stránkování. A zde je ten problém, stránkování. U MySQL bych šel klasicky, přes: SELECT .... LIMIT x,y. Bohužel Oracle nic takového jako LIMIT nemá. Co teď? Parsovat SQL dotaz podle použitého DBMS? Ano. Ale s tím, že někdo něco takového již napsal. Samotný EntityManager obsahuje metody "setMaxResults(int arg)" a "setFirstResult(int arg)". Takže o jednu starost méně :)
Občas mi to přijde jako věčný boj. Každý druhý (v PHP) si píše vlastní databázové layery, tvrdí jak vše funguje, ale jen do doby, než přijde první požadavek, který nebyl očekáván podle specifikace používaného frameworku.
Doufám, že jednou bude svět natolik ideální, že skutečná nezávislost bude brána jako stadard pro psaní aplikací pro DBMS.
Důvodů je několik:
- aplikace se může natolik rozsrůst, že stávající DBMS může být nevyhovující
- vývoj v oblasti databází jde stále vpřed a s tím souvisí i změny v SQL jazyku
- samotný model struktury dat by měl být definován v aplikaci, kde by měl být odstíněn od nějakého SQL
- zdroje mohou být různé (databáze, soubory, vzdálená volání, ...)
- aplikace může být vyvíjena bez použití databáze, která může přijít v pozdější fázi
Jak už to tak bývá, tak úspěch projektu je závislý od prvotní analýzy. Nechtějme tedy vše řešit hned od počátku. Jistě je bezpečnější si nechat otevřená zadní vrátka pro dané změny, které by mohly mít fatální následky.
Kompromis
Bohužel, nežijeme v ideálním světě, kde by vše bylo nalinkované tak, jak bychom si přáli. Uvedu jeden příklad, který mě přesvědčil o tom, že vytvořit aplikaci, která by byla skutečně nezávislá na DBMS je nemožné.
Pro načítání dat z jiných zdrojů, jsem použil Timer metody z EJB3, které mají tu vlastnost, že jsem schopný vytvořit si vlastní plánování plnění. Na persistenci jsem použil JPA. Když jsem zjistil, že JPA má možnost přiřadit listener na danou entitu, hned jsem si tuto vlastnost spojil s tím, že nebudu muset psát žádné triggery a hezky půjdu touto cestou.
To jsem si ovšem neuvědomil, že při dávkovém zpracování je JPA a EntityManager natolik náročný způsob, že jsem byl nucen přejít na nízkoúrovňové JDBC. Výhodou samozřejmě bylo extrémní zrychlení, ale nevýhodou, že daný Listener je v podstatě k ničemu. Ve finále jsem byl nucen napsat trigger a tím utnout možnost, že aplikační logika se postará o vše potřebné.
Vše není tak černé
I když jsem opustil snadnou přenostitelnost, stále mi zůstává možnost psát tu aplikaci tak, aby byl doménový model to hlavní a já byl co nejvíce odstíněn od DBMS. Přece jen, toho dávkového spracování zase není tolik, aby se to nedalo kdykoli změnit.
Používám 2 základní zdroje: MySQL a Oracle. Při klasickém přístupu jsou si obě databáze velice podobné. Je zde ovšem několik rozdílů, které jsou dost zásadní. Opět uvedu příklad, který toto vystihuje:
Chci nějaký základní reportovací nástroj, který bude pracovat tak, že uživatel napíše SQL dotaz, systém ho zpracuje a vrátí tabulku. Tabulku, která bude obsahovat možnost stránkování. A zde je ten problém, stránkování. U MySQL bych šel klasicky, přes: SELECT .... LIMIT x,y. Bohužel Oracle nic takového jako LIMIT nemá. Co teď? Parsovat SQL dotaz podle použitého DBMS? Ano. Ale s tím, že někdo něco takového již napsal. Samotný EntityManager obsahuje metody "setMaxResults(int arg)" a "setFirstResult(int arg)". Takže o jednu starost méně :)
Občas mi to přijde jako věčný boj. Každý druhý (v PHP) si píše vlastní databázové layery, tvrdí jak vše funguje, ale jen do doby, než přijde první požadavek, který nebyl očekáván podle specifikace používaného frameworku.
Doufám, že jednou bude svět natolik ideální, že skutečná nezávislost bude brána jako stadard pro psaní aplikací pro DBMS.
středa 25. července 2007
Novinky 1
Jelikož jsem v poslední době dost zaměstnán a nemám tolik času na psaní článků, rozhodl jsem se, že se alespoň občas pokusím sepsat pár novinek, které mne na internetu v poslední době zaujaly. Jedná se často o věci, se kterými mám osobní zkušenosti a mohu se výjádřit k jejich použití, či jsem do dané oblasti zainteresován.
Takže jedem...
JUG -Eclipse vs. Betbeans
První věcí je asi JUG, který měl jedno téma, a tím bylo Netbeans RCP vs. Eclipse RCP. Až bude k dispozici video, doporučuji ho stáhnout. Za oba tábory mluvili lidé, kteří jsou v této oblasti odborníci. Zejména Jarda Tulach, který je hlavním vývojářem NetBeans a zná tuto platformu do základů.
Eclipse 3.3 a PDT
Jistě spousta vývojářů zaznamenala, že vyšla nová verze tohoto oblíbeného nástroje a platformy. Nová verze nese označení Eclipse Europa. Současně s vydáním nové verze se i u ZENDu sebrali a provedli drobné úpravy svého PDT (PHP Development Tools) nástroje, který je nyní kompatibilní s novou verzí Eclipse. Samotná instalace je naprosto triviální. Stačí přidat do "Help -> Software Updates -> Find and install -> New features" nový remote site. URL adresa je http://download.eclipse.org/tools/pdt/updates/. Pro správné fungování je samozřejmě zapotřebí WST (Web Standard Tools).
Osobně jsem se hned pustil do aktualizace a nyní již na verzi 3.3 s PDT mohu opět fungovat.
NetBeans 6 M10
Ještě před vydáním Eclipse 3.3 vyšla nová milestone od Netbeans. Hned jsem tuto verzi vyzkoušel a i přes menší prodlevu při startu musím říct, že je verze naprosto stabilní. Změny se dočkala zejména textová část, která při psaní java kodu nabízí nové možnosti. Jednou z nich je i změněný přistup k refactoringu: Alt + Ins vyvolá popupmenu s možnostmi pro daný focus kurzoru. Další věcí, která mě potěšila, byla možnost přehazování a duplikování řádků (tak jak jsem byl zvyklý z Eclipse), pomocí Ctrl + Shift + (Up|Down) můžete řádky duplikovat a pomocí Alt + Shift + (Up|Down) řádky přesouvat. Zdánlivě maličkost, ale mně osobně udělala radost. Změn se dočkala i zvýrazněná syntaxe, kde je již možnost lepší orientace mezi klasickými parametry, které přišly z metody a mezi atributy třídy. Nezaznamenal jsem větší problémy, ba co víc, na této verzi stavím vlastní desktop aplikaci, která jde zatím také bez problémů.
phpMinAdmin
Poslední novinkou, kterou se zde budu zabývat, je nástroj od Jakuba Vrány phpMinAdmin. Na jeho webu se můžete dočíst, co ho vedlo k tomuto činu. Osobně si myslím, že pro malé projekty, které jsou poslány do víru internetu, je tento nástroj velice užitečný. Pokud stavíte menší aplikace a nemáte vzdalený přístup k MySQL, doporučuji se podívat, zda by Vám tato "malá aplikace" nepostačila. Samozřejmostí je zvážit phpMyAdmina, který je přece jen robustnějším nástrojem.
Takže jedem...
JUG -Eclipse vs. Betbeans
První věcí je asi JUG, který měl jedno téma, a tím bylo Netbeans RCP vs. Eclipse RCP. Až bude k dispozici video, doporučuji ho stáhnout. Za oba tábory mluvili lidé, kteří jsou v této oblasti odborníci. Zejména Jarda Tulach, který je hlavním vývojářem NetBeans a zná tuto platformu do základů.
Eclipse 3.3 a PDT
Jistě spousta vývojářů zaznamenala, že vyšla nová verze tohoto oblíbeného nástroje a platformy. Nová verze nese označení Eclipse Europa. Současně s vydáním nové verze se i u ZENDu sebrali a provedli drobné úpravy svého PDT (PHP Development Tools) nástroje, který je nyní kompatibilní s novou verzí Eclipse. Samotná instalace je naprosto triviální. Stačí přidat do "Help -> Software Updates -> Find and install -> New features" nový remote site. URL adresa je http://download.eclipse.org/tools/pdt/updates/. Pro správné fungování je samozřejmě zapotřebí WST (Web Standard Tools).
Osobně jsem se hned pustil do aktualizace a nyní již na verzi 3.3 s PDT mohu opět fungovat.
NetBeans 6 M10
Ještě před vydáním Eclipse 3.3 vyšla nová milestone od Netbeans. Hned jsem tuto verzi vyzkoušel a i přes menší prodlevu při startu musím říct, že je verze naprosto stabilní. Změny se dočkala zejména textová část, která při psaní java kodu nabízí nové možnosti. Jednou z nich je i změněný přistup k refactoringu: Alt + Ins vyvolá popupmenu s možnostmi pro daný focus kurzoru. Další věcí, která mě potěšila, byla možnost přehazování a duplikování řádků (tak jak jsem byl zvyklý z Eclipse), pomocí Ctrl + Shift + (Up|Down) můžete řádky duplikovat a pomocí Alt + Shift + (Up|Down) řádky přesouvat. Zdánlivě maličkost, ale mně osobně udělala radost. Změn se dočkala i zvýrazněná syntaxe, kde je již možnost lepší orientace mezi klasickými parametry, které přišly z metody a mezi atributy třídy. Nezaznamenal jsem větší problémy, ba co víc, na této verzi stavím vlastní desktop aplikaci, která jde zatím také bez problémů.
phpMinAdmin
Poslední novinkou, kterou se zde budu zabývat, je nástroj od Jakuba Vrány phpMinAdmin. Na jeho webu se můžete dočíst, co ho vedlo k tomuto činu. Osobně si myslím, že pro malé projekty, které jsou poslány do víru internetu, je tento nástroj velice užitečný. Pokud stavíte menší aplikace a nemáte vzdalený přístup k MySQL, doporučuji se podívat, zda by Vám tato "malá aplikace" nepostačila. Samozřejmostí je zvážit phpMyAdmina, který je přece jen robustnějším nástrojem.
úterý 5. června 2007
OOP v PHP5 díl.7 - návrhové vzory (design patterns)
Při programování objektovým způsobem se dost často dostanete do fáze, kdy si nebudete jistí, jak máte danou třídu či samotnou práci s instancí provést. Může se jednat o triviální problémy typu: připojení k DB či složitější věci jako návrh MVC Frameworku.
Na tyto problémy mysleli čtyři chlapíci (Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides), kteří jsou autory knihy Design Patterns: Elements of Reusable Object-Oriented Software. Kniha se brzy stala natolik oblíbenou, že je dodnes povážována za nejlepší dílo ohledně OOP. Více o této historii se můžete dozvědět např. na Wikipedii.
Samotné návrhové vzory nejsou standardem, ale doporučením, jak při psaní máte postupovat. Já se nyní pokusím sepsat, jak je to
s návrhovými vzory v PHP. Vyberu jen ty nejjednodušší a nejčastěji používané a ukáži, jak je to s jejich implementací.
1. Singleton (jedináček)
Jak již název napovídá, jedná se o objekt, který je vytvořen pouze jednou. Tento návrhový vzor můžete využít například u připojení k databázi, kde si jasně řeknete, že byste neradi, aby Vám PHP otevíralo více spojení.
Samotný fígl spočívá v tom, že instance samotného objektu je uložena jako statický atribut třídy a objekt je vytvořen pouze v případě, že je atribut null. Konstruktor třídy je nastaven jako private, aby se nikdo nemohl snažit vytvořit objekt pomocí new Pripojeni();. Samotní vývojáři v PHP ale přišli na to, že Singleton nelze na 100% vytvořit. Důvody proč tomu tak je, můžete najít v PHP dokumentaci, zejména v komentářích.
2. Factory
Tento vzor slouží k tomu, že vytvořím jednoduchou třídu, ve které vytvořím metodu, která podle přijímaného parametru vrací ten či onen objekt.
Z kódu je jasné, že samotný vzor lze použít například k připojení na ruznorodé databáze.
3. Transfer object
Pokud skutečně chceme programovat objektově a programovat co nejefektivněji, nevyhneme se tomuto vzoru. Jedná se v podstatě o jednoduché třídy, které mají za úkol preprezentovat přenášená data. Nějčastěji se můžeme s tímto vzorem setkat v ORM nástrojích, kde jsou jednotlivé tabulky mapovány jako třídy a jedna instance je ekvivalentní jednomu řádku v databázi.
Často se také můžeme setkat s tím, že samotné objekty jsou příliš složité (tzn. odkazují se na další objekty jako v případě zaměstnance a střediska). Pokud se tak stane a naše aplikace přenáší velké množství dat, je nasnadě použít tzv. DTO (data transfer object), což je v podstatě jednoduchý objekt, který nemá jako atributy třídy další objekty, ale primitivní datové typy. V případě zaměstnance by to bylo číslo střediska, což je primární a unikatní klíč střediska. O tom, jak tvořit samotné DTO je spíše otázka té či oné aplikace a její složitosti a náročnosti.
4. Facade
Při vývoji softwaru se programátoři dostávali do situací, kdy potřebovali mít jednotlivé vlastnosti na jednom místě. Ať už z důvodu přehlednosti, rychlosti či provázanosti. Vzor facade řeší roztříštěnost vaší aplikace. Představme si, že máme vytvořit modul na správu zaměstnanců, která bude řešit jak editace zaměstnance, tak třeba i střediska. Jedna z možností je, že budeme zpětně složitě dohledávat objekty na editaci jednotlivých kategorií a nebo si vytvoříme jasně definovaná pravidla:
Tento jednoduchý objekt pracuje se zamestnanci. Třídu na editaci středisek si jistě dovedete představit. Nyní se vrátím k zadanému úkolu. Naprogramovat modul pro editaci zamestnance i s editaci střediska. Jedna z možností je, na view vrstvě volat tyto třídy pro práci a nebo si pěkne zhlukovat dané objekty do jednoho.
Samozřejmě by se dalo najít spoustu příkladů použití. Pokud při programování někdo přemýšlí hlavou, dojde mu, že takto postupovat, znamená, že co nejvíce odstinuji view vrstvu od aplikační logiky.
5. Iterator
Posledním návrhovým vzorem, kterým se zde budu zabývat je Iterator. Již dříve jsem psal, že PHP 5 má k dispozici rozhranní Iterator, které podporuje tento návrhový vzor. Takže, oč jde. Nejednou se stane, že potřebujeme na určitou kolekci dat použít nejaký cyklus, ve kterém bych mohl daná data procházet. Na jednu stranu, mohu sice použít vlastní logiku na procházení daty, ale také mám možnost připravit si jakousi formičku pro určitá data, která se budou procházet. Příkladem může být, že vytvořím objekt s počátečním datumem (1.2.2007) a konečným datem (5.7.2007) a budu chtít daná data procházet po dni. Nebo budu chtít procházet písmena od B do X po jednotlivém pismenu. Na tyto a další operace se náramně hodí použít tzv. Iterator. Iterátor jako takový má podle interface přesně definované metody, které musí třída implementující rozhranní Iterátor obsahovat:
Podle těchto jasných pravidel jsem schopen vytvořit třídu, která bude procházet libovolný seznam dat podle určitých kriteríí či podle vlastní logiky. Velkou výhodou je znovupoužitelnost a také zapouzdřenost. Jiný programátor, kterému tuto třídu poskytnete vůbec nemusí vědět, jak daná logika pracuje, stačí, že implementuje Iterator a již je schopen, podle zadaných vstupních parametrů s třídou pracovat.
Návrhových vzorů samozřejmě existuje mnohem více. Navíc PHP je objektově dost omezené, takže ne vždy je zrovna ideální řešení právě ten či onen vzor. Někdy bývá lepší si některé věci prostě naprogramovat po svém. Na druhou stranu, bývá dobrým zvykem, že pokud se budu řídit určitými kriterii, které jsem v minulých článcích popsal, měl by vývojář míti klidné spaní. Na mysli mám zejména dodržování specifik jako jsou setry, getry, nazvosloví či dokumentace.
I když není objektově orientované programování zrovna jednoduchá záležitost, tak věřím, že pro nikoho není překážkou se základní principy naučit.
To by bylo k PHP asi tak vše. Jelikož jsem slíbíl, že daný díl dopíšu, stalo se tak. Nyní jsem již situován jiným směrem, takže PHP je pro mě pouze vedlejší záležitost. Přeji mnoho úspěchů při objektovém programování, ať už v jakémkoli jazyce.
Na tyto problémy mysleli čtyři chlapíci (Erich Gamma, Richard Helm, Ralph Johnson a John Vlissides), kteří jsou autory knihy Design Patterns: Elements of Reusable Object-Oriented Software. Kniha se brzy stala natolik oblíbenou, že je dodnes povážována za nejlepší dílo ohledně OOP. Více o této historii se můžete dozvědět např. na Wikipedii.
Samotné návrhové vzory nejsou standardem, ale doporučením, jak při psaní máte postupovat. Já se nyní pokusím sepsat, jak je to
s návrhovými vzory v PHP. Vyberu jen ty nejjednodušší a nejčastěji používané a ukáži, jak je to s jejich implementací.
1. Singleton (jedináček)
Jak již název napovídá, jedná se o objekt, který je vytvořen pouze jednou. Tento návrhový vzor můžete využít například u připojení k databázi, kde si jasně řeknete, že byste neradi, aby Vám PHP otevíralo více spojení.
class Pripojeni {
private static $instance = null;
private function __construct() {}
public static function getInstance() {
if (self::$instance == null) {
$class = __CLASS__;
self::$instance = new $class;
}
return self::$instance;
}
}Samotný fígl spočívá v tom, že instance samotného objektu je uložena jako statický atribut třídy a objekt je vytvořen pouze v případě, že je atribut null. Konstruktor třídy je nastaven jako private, aby se nikdo nemohl snažit vytvořit objekt pomocí new Pripojeni();. Samotní vývojáři v PHP ale přišli na to, že Singleton nelze na 100% vytvořit. Důvody proč tomu tak je, můžete najít v PHP dokumentaci, zejména v komentářích.
2. Factory
Tento vzor slouží k tomu, že vytvořím jednoduchou třídu, ve které vytvořím metodu, která podle přijímaného parametru vrací ten či onen objekt.
class Factory {
const MYSQL = "mysql";
const ORACLE = "oracle";
public static function getDBMS($dbms) {
if ($dbms == self::MYSQL) {
return new MySQL();
} else if ($dbms == self::ORACLE) {
return new Oracle();
} else {
throw new Factory_Exception("Neznamy ovladac");
}
}
}Z kódu je jasné, že samotný vzor lze použít například k připojení na ruznorodé databáze.
3. Transfer object
Pokud skutečně chceme programovat objektově a programovat co nejefektivněji, nevyhneme se tomuto vzoru. Jedná se v podstatě o jednoduché třídy, které mají za úkol preprezentovat přenášená data. Nějčastěji se můžeme s tímto vzorem setkat v ORM nástrojích, kde jsou jednotlivé tabulky mapovány jako třídy a jedna instance je ekvivalentní jednomu řádku v databázi.
class Zamestnanec {
private $osobniCislo;
private $jmeno;
private $prijmeni;
/**
* @var Stredisko
*/
private $stredisko;
// ... setry getryČasto se také můžeme setkat s tím, že samotné objekty jsou příliš složité (tzn. odkazují se na další objekty jako v případě zaměstnance a střediska). Pokud se tak stane a naše aplikace přenáší velké množství dat, je nasnadě použít tzv. DTO (data transfer object), což je v podstatě jednoduchý objekt, který nemá jako atributy třídy další objekty, ale primitivní datové typy. V případě zaměstnance by to bylo číslo střediska, což je primární a unikatní klíč střediska. O tom, jak tvořit samotné DTO je spíše otázka té či oné aplikace a její složitosti a náročnosti.
4. Facade
Při vývoji softwaru se programátoři dostávali do situací, kdy potřebovali mít jednotlivé vlastnosti na jednom místě. Ať už z důvodu přehlednosti, rychlosti či provázanosti. Vzor facade řeší roztříštěnost vaší aplikace. Představme si, že máme vytvořit modul na správu zaměstnanců, která bude řešit jak editace zaměstnance, tak třeba i střediska. Jedna z možností je, že budeme zpětně složitě dohledávat objekty na editaci jednotlivých kategorií a nebo si vytvoříme jasně definovaná pravidla:
class ZamestnanecEdit {
public function add(Zamestnanec $zam) { /* prida zamestnance */ }
public function remove(Zamestnanec $zam) { /* smaze zamestnance - muze vyhodit vyjimku ZamestnanecEditException */ }
public function save(Zamestnanec $zam) { /* ulozi zmeny daneho zamestnance */ }
public function find($cisloZamestnance) { /* return Zamestnanec */ }
public function findAll() { /* vrati array vsech zamestnancu */ }
}Tento jednoduchý objekt pracuje se zamestnanci. Třídu na editaci středisek si jistě dovedete představit. Nyní se vrátím k zadanému úkolu. Naprogramovat modul pro editaci zamestnance i s editaci střediska. Jedna z možností je, na view vrstvě volat tyto třídy pro práci a nebo si pěkne zhlukovat dané objekty do jednoho.
class ZamestnanciEditaceFacade {
/**
* @var ZamestnanecEdit
*/
private $zamestnanecEditace;
/**
* @var StrediskoEdit
*/
private $strediskoEditace;
public function __construct() {
$this->zamestnanecEditace = new ZamestnanecEditace();
$this->strediskoEditace = new StrediskoEditace();
}
public function addZamestnanec(Zamestnanec $zamestnanec) {
$this->zamestnanecEditace->add($zamestnanec);
}
public function addStredisko(Stredisko $stredisko) {
$this->strediskoEditace->add($stredisko);
}
// .....Samozřejmě by se dalo najít spoustu příkladů použití. Pokud při programování někdo přemýšlí hlavou, dojde mu, že takto postupovat, znamená, že co nejvíce odstinuji view vrstvu od aplikační logiky.
5. Iterator
Posledním návrhovým vzorem, kterým se zde budu zabývat je Iterator. Již dříve jsem psal, že PHP 5 má k dispozici rozhranní Iterator, které podporuje tento návrhový vzor. Takže, oč jde. Nejednou se stane, že potřebujeme na určitou kolekci dat použít nejaký cyklus, ve kterém bych mohl daná data procházet. Na jednu stranu, mohu sice použít vlastní logiku na procházení daty, ale také mám možnost připravit si jakousi formičku pro určitá data, která se budou procházet. Příkladem může být, že vytvořím objekt s počátečním datumem (1.2.2007) a konečným datem (5.7.2007) a budu chtít daná data procházet po dni. Nebo budu chtít procházet písmena od B do X po jednotlivém pismenu. Na tyto a další operace se náramně hodí použít tzv. Iterator. Iterátor jako takový má podle interface přesně definované metody, které musí třída implementující rozhranní Iterátor obsahovat:
- rewind() - nastavuje na první položku v seznamu
- current() - vrací aktuální položku seznamu
- key() - vrací klíč pole
- next() - vrací následující položku seznamu
- valid() - zjišťuje, zda existuje ještě nějaká položka
Podle těchto jasných pravidel jsem schopen vytvořit třídu, která bude procházet libovolný seznam dat podle určitých kriteríí či podle vlastní logiky. Velkou výhodou je znovupoužitelnost a také zapouzdřenost. Jiný programátor, kterému tuto třídu poskytnete vůbec nemusí vědět, jak daná logika pracuje, stačí, že implementuje Iterator a již je schopen, podle zadaných vstupních parametrů s třídou pracovat.
Návrhových vzorů samozřejmě existuje mnohem více. Navíc PHP je objektově dost omezené, takže ne vždy je zrovna ideální řešení právě ten či onen vzor. Někdy bývá lepší si některé věci prostě naprogramovat po svém. Na druhou stranu, bývá dobrým zvykem, že pokud se budu řídit určitými kriterii, které jsem v minulých článcích popsal, měl by vývojář míti klidné spaní. Na mysli mám zejména dodržování specifik jako jsou setry, getry, nazvosloví či dokumentace.
I když není objektově orientované programování zrovna jednoduchá záležitost, tak věřím, že pro nikoho není překážkou se základní principy naučit.
To by bylo k PHP asi tak vše. Jelikož jsem slíbíl, že daný díl dopíšu, stalo se tak. Nyní jsem již situován jiným směrem, takže PHP je pro mě pouze vedlejší záležitost. Přeji mnoho úspěchů při objektovém programování, ať už v jakémkoli jazyce.
Poslední radou by mělo být asi následující: OOP není cíl, ale prostředek k dosažení cíle. Proto neberte OOP jako něco spásného. Ba naopak, dost často se dostanete do problémů, které nebude jednoduché vyřešit.
čtvrtek 10. května 2007
Java EE 5 - MySQL -> Glassfish -> Swing díl 1.
V komentáři jsem dostal připomínku, že bych měl spíše napsat něco jednoduchého, co by pochopil i člověk, který o Jave a použitých technologií nic neví.
Rozhodl jsem se, že se pokusím sepsat "step-by-step" tutoriál, který by prošel základní vývoj jednoduchoučké aplikace v Jave.
Důvodem je možná i to, že aplikace psané v Jave, které mají míti třívrstvou architekturu client-server-databáze, nejsou jen o "core" programování. Mám na mysli nastavení, které není zrovna triviální. Možná i to je důvodem, proč někteří lidé skončí hned na startu.
Takže, co bude výsledkem:
Desktopová aplikace, která komunikuje s aplikačním serverem, obsahuje business logiku a je navázána na databázi přes daný server.
Jinými slovy, jedná se o třívrstvou architekturu klient-server-databáze. Za klienta si můžete dosadit jak webovou tak desktopovou aplikaci. Výhodou třívrstvé architektury je to, že klient neobsahuje aplikační logiku, která může být natolik náročná, že je lepší, aby ji spravoval výkonný server. Výhod je samozřejmě více, ale nám bude stačit tato základní.
Aplikace je celá psaná v Jave. Na klienta použiji Swing, který je součástí implementace Javy od SUNu a server bude glassfish (Java Sun Application Server 9), který je volně dostupný. Databáze bude MySQL 5.0.
Veškeré potřebné věci je možné získat zdarma, což je v dnešní době ohromná výhoda, zejména pokud si uvědomím, jakou možnost mi samotná Java EE 5 nabízí.
Co všechno budu potřebovat?
Instalace je jednoduchá. Nainstaluji uvedené produkty, tak jak jsem je vypsal. Pro počáteční start je to dostačující. Samotný MySQL Connector/J zatím uložím na disk, bude se hodit až v pozdější fázi.
Rozhodl jsem se, že se pokusím sepsat "step-by-step" tutoriál, který by prošel základní vývoj jednoduchoučké aplikace v Jave.
Důvodem je možná i to, že aplikace psané v Jave, které mají míti třívrstvou architekturu client-server-databáze, nejsou jen o "core" programování. Mám na mysli nastavení, které není zrovna triviální. Možná i to je důvodem, proč někteří lidé skončí hned na startu.
Takže, co bude výsledkem:
Desktopová aplikace, která komunikuje s aplikačním serverem, obsahuje business logiku a je navázána na databázi přes daný server.
Jinými slovy, jedná se o třívrstvou architekturu klient-server-databáze. Za klienta si můžete dosadit jak webovou tak desktopovou aplikaci. Výhodou třívrstvé architektury je to, že klient neobsahuje aplikační logiku, která může být natolik náročná, že je lepší, aby ji spravoval výkonný server. Výhod je samozřejmě více, ale nám bude stačit tato základní.
Aplikace je celá psaná v Jave. Na klienta použiji Swing, který je součástí implementace Javy od SUNu a server bude glassfish (Java Sun Application Server 9), který je volně dostupný. Databáze bude MySQL 5.0.
Veškeré potřebné věci je možné získat zdarma, což je v dnešní době ohromná výhoda, zejména pokud si uvědomím, jakou možnost mi samotná Java EE 5 nabízí.
Co všechno budu potřebovat?
- JDK 6 - Java Development Kit
- Java System Application Server 9
- NetBeans 5.5.
- MySQL 5.0.
- MySQL Connector/J 5.0.5
Instalace je jednoduchá. Nainstaluji uvedené produkty, tak jak jsem je vypsal. Pro počáteční start je to dostačující. Samotný MySQL Connector/J zatím uložím na disk, bude se hodit až v pozdější fázi.
V příštím díle ukáži, jak po instalaci nakonfiguruji základní parametry pro chod daných produktů.
pátek 27. dubna 2007
Java EE5 - stand-alone client
V minulém článku jsem nastínil, jakým způsobem se dá vyvíjet enterprise aplikace psaná v Jave. Samozřejmostí je využití různých metodik, podle kterých se řídí celý vývojový tým. Dříve, než mohu řešit rozsáhlé aplikace, musím ovšem míti dostatek zkušeností a znalostí. Já se chci více zaměřit na menší problémy, na které začátečník (stejně jako já) může narazit.
Budu předpokládat, že máte již základní znalosti o tom, co je to EJB, JPA a k čemu jsou enterprise aplikace určeny. Pokud by někdo hledal zdroj informací, osobně doporučuji tento tutoriál. Samotné čtení není nijak náročné. Předpokladem je základní znalost OOP, Javy, popřípadě databázových systémů typu Oracle, MySQL, .....
Osobně jsem si po přečtení celého tutoriálu udělal obrázek o tom, co je to vlastně Java EE 5 a k jakým účelům mohu něco tak rozsáhlého využít. V dnešní době je velký boom webových aplikací, které na nás srší ze všech stran. U samotné Javy se domnívám, že to není zrovna nejjednodušší oblast, kterou by se mělo začínat. Osobně jsem se raději více zaměřil na desktop, kde pomocí Swingu jsem schopen vytvořit "sexy" aplikaci, která bude splňovat základní podmínky. Každému, kdo s Javou začíná, doporučuji právě desktop.
Nyní již k samotné stand-alone aplikaci:
Přístup k EJB se dělí na dvě části:
O tom, který přístup daná EJB využívá se definuje anotací nad samotným interfacem, který samotná beana implemetuje:
Rozdíl mezi Locale a Remote je ten, že Remote může volat aplikace, která běží v jiné VM. To se samozřejmě hodí ve chvíli, kdy potřebujeme napsat desktopovou aplikaci, která poběží na klientovi, který má vlastní instalaci JRE. Jiná VM není podmínkou pro běh Remote EJB.
Možná někoho napadne, proč tedy všude nevyužít Remote, když mohu volat tuto EJB kdekoli. Důvodem je výkon. Proto, pokud volám EJB uvnitř glassfishe (aplikační server), využiji k tomu Locale. Dost často mi z toho vychází, že implementuji obě interface na beanu. Navíc je také rozdílný způsob volání Locale a Remote EJB.
To by bylo k business logice. Vytvoříme si jednoduchou EJB, která bude mít Remote interface, kterou poté vystavím (deploy) na glassfish.
Nyní, se pustím do desktopové aplikace, která poběží na klientech a bude vzdáleně volat EJB ze serveru.
Prvním předpokladem je přidání celého EJB projektu v podobě distribuovaného jar souboru do aplikace. Jinými slovy, musí být někde, kde na něj samotná aplikace uvidí. V netbeans stačí do library includovat náš "projekt-ejb". Automaticky se hledá distribuovatelný jar soubor, který se defaultně nachází v adresáři dist.
Dále je potřeba přilinkovat tyto soubory:
Všechny uvedené soubory naleznete v adresáři instalovaného glassfishe (GLASSFISH_PATH/lib).
Tím bychom měli připravenou stand-alone aplikaci k tomu, aby nám byla schopna vzdáleně volat EJB.
Nyní již k samotnému kódu:
Za a dosadíme vlastní parametry pro volání na server. Výchozím portem je 3700. Pokud testuji aplikaci na localhostu pod stejnou VM, jako mám server, není třeba properties nastavovat. Mohu zavolat InitialContext bez properties. Druhou možností je také nastavit parametricky tyto údaje. Pro další informace doporučuji glassfish: EJB FAQ.
Zapoměl jsem zmínit jednu důležitou věc. Pokud vzdáleně volám EJB, musím někde nastavit JNDI (název, pod kterým je vzdálená aplikace schopna nalézt EJB). Existuje několik možností, buď definovat daný název pomocí XML nebo pomocí anotací.
Záměrně jsem některé názvosloví popsal vlastními slovy. Důvodem je to, že při tak ohromném množství nových výrazů nejsem schopen se ihned orientovat. Také jsem ovšem danou problematiku nepsal stylem step-by-step. Zde by se jednalo o neštastné řešení, zejména ve chvíli, kdy se jedná o rozsáhlejší problematiku. Zde bych doporučil použít metodiku (pokus/omyl) :) Jinými slovy, bez přemýšlení není člověk schopen pochopit daný úkol.
Budu předpokládat, že máte již základní znalosti o tom, co je to EJB, JPA a k čemu jsou enterprise aplikace určeny. Pokud by někdo hledal zdroj informací, osobně doporučuji tento tutoriál. Samotné čtení není nijak náročné. Předpokladem je základní znalost OOP, Javy, popřípadě databázových systémů typu Oracle, MySQL, .....
Osobně jsem si po přečtení celého tutoriálu udělal obrázek o tom, co je to vlastně Java EE 5 a k jakým účelům mohu něco tak rozsáhlého využít. V dnešní době je velký boom webových aplikací, které na nás srší ze všech stran. U samotné Javy se domnívám, že to není zrovna nejjednodušší oblast, kterou by se mělo začínat. Osobně jsem se raději více zaměřil na desktop, kde pomocí Swingu jsem schopen vytvořit "sexy" aplikaci, která bude splňovat základní podmínky. Každému, kdo s Javou začíná, doporučuji právě desktop.
Nyní již k samotné stand-alone aplikaci:
Přístup k EJB se dělí na dvě části:
- Lokální (@Locale)
- Vzdálený (@Remote)
O tom, který přístup daná EJB využívá se definuje anotací nad samotným interfacem, který samotná beana implemetuje:
@Remote
public interface UzivateleFacadeRemote {
public List findAll();
} Rozdíl mezi Locale a Remote je ten, že Remote může volat aplikace, která běží v jiné VM. To se samozřejmě hodí ve chvíli, kdy potřebujeme napsat desktopovou aplikaci, která poběží na klientovi, který má vlastní instalaci JRE. Jiná VM není podmínkou pro běh Remote EJB.
Možná někoho napadne, proč tedy všude nevyužít Remote, když mohu volat tuto EJB kdekoli. Důvodem je výkon. Proto, pokud volám EJB uvnitř glassfishe (aplikační server), využiji k tomu Locale. Dost často mi z toho vychází, že implementuji obě interface na beanu. Navíc je také rozdílný způsob volání Locale a Remote EJB.
To by bylo k business logice. Vytvoříme si jednoduchou EJB, která bude mít Remote interface, kterou poté vystavím (deploy) na glassfish.
Nyní, se pustím do desktopové aplikace, která poběží na klientech a bude vzdáleně volat EJB ze serveru.
Prvním předpokladem je přidání celého EJB projektu v podobě distribuovaného jar souboru do aplikace. Jinými slovy, musí být někde, kde na něj samotná aplikace uvidí. V netbeans stačí do library includovat náš "projekt-ejb". Automaticky se hledá distribuovatelný jar soubor, který se defaultně nachází v adresáři dist.
Dále je potřeba přilinkovat tyto soubory:
- appserv-admin.jar
- appserv-deployment-client.jar
- appserv-ext.jar
- appserv-rt.jar
- javaee.jar
Všechny uvedené soubory naleznete v adresáři instalovaného glassfishe (GLASSFISH_PATH/lib).
Tím bychom měli připravenou stand-alone aplikaci k tomu, aby nám byla schopna vzdáleně volat EJB.
Nyní již k samotnému kódu:
Properties properties = System.getProperties();
properties.setProperty("org.omg.CORBA.ORBInitialHost", );
properties.setProperty("org.omg.CORBA.ORBInitialPort", );
Context ctx = new InitialContext(properties);
// po pripravene inicializaci vzdalene zavolam EJB
UzivateleFacadeRemote facade = (UzivateleFacadeRemote) ctx.lookup("RemoteName"); Za
Zapoměl jsem zmínit jednu důležitou věc. Pokud vzdáleně volám EJB, musím někde nastavit JNDI (název, pod kterým je vzdálená aplikace schopna nalézt EJB). Existuje několik možností, buď definovat daný název pomocí XML nebo pomocí anotací.
Záměrně jsem některé názvosloví popsal vlastními slovy. Důvodem je to, že při tak ohromném množství nových výrazů nejsem schopen se ihned orientovat. Také jsem ovšem danou problematiku nepsal stylem step-by-step. Zde by se jednalo o neštastné řešení, zejména ve chvíli, kdy se jedná o rozsáhlejší problematiku. Zde bych doporučil použít metodiku (pokus/omyl) :) Jinými slovy, bez přemýšlení není člověk schopen pochopit daný úkol.
Příště se podívám na JPA a FetchType. K čemu slouží LAZY a EAGER. A jak je to vlastně s defaultní hodnotou mimo a uvnitř glassfishe.
pátek 20. dubna 2007
Java EE 5 - začátky aneb konec PHP
Každý, kdo začně blíže studovat Java EE5, získá celkový přehled o tom, jak je Java rozdělena do několika vstev. Společně s tím, ale vyvstane spoustu otázek, jak provést to či ono. Některé věci totiž nejsou úplně zřejmé a pokud chci tvořit projekt, který bude provázán s dalšími vrstvami, dostanu se dost často do potíží s nastavením a vůbec spuštěním jednotlivých částí.
Na začátku je důležité si zvolit správnou technologii. Pokud zvolím Javu budu muset řešit další věc a tou je její ohromné množství frameworků. Osobně jsem toto vyřešil tak, že se držím (pokud je to jen možné) standardů SUNu.
Takže co je cílem: Vytvořit intranetovou aplikaci, která bude pokrývat požadavky firmy. Od výrobních procesů, přes ekonomické záležitosti až po různé schvalovací procesy. Klientem bude webová či desktopová aplikace. Ve chvíli, kdy potřebuji komunikovat se sériovým portem, musím volit desktop. Když budu řešit výpis sestav, použiji zase webovou aplikaci. Obě tyto aplikace musejí míti stejnou základnu (databázi). V lepším případě základnou bude business logika pro obě aplikace.
Jak jsem psal výše, zvolil jsem nejpoužívanější frameworky, které jsou navíc i standardy. Na persistenci (připojení k databázi) TopLink od Oracle. Jako databázi MySQL 5.0. Na namapování relačních tabulek do objektů JPA. Samotná business logika je řešena přes EJB3.0. Na webovou část jsem zvolil JSF společně s Facelets (i když Facelets není standard, dost pomáhá samotnému JSF). Na desktop Swing. Aplikační server je Sun Java Application Server 9 (glassfish).
Takže zvolené součásti mám úspěšně za sebou. Nyní přistoupím k samotné implementaci. První věcí, kterou musím udělat, je rozjet MySQL v glassfish. Toto udělám jednoduše tak, že nahraji java-mysql-connector do adresáře PATH_GLASSFISH/lib. V samotné admin konsoli (webová aplikace pro správu glassfishe), vytvořím connection pool a jdbc resource pro mysql a danou databázi.
Nyní přistoupím k tvorbě business logiky. Po vytvoření enterprise projektu ptovedu vytvoření persistence pomocí TopLinku. Po namapování glassfishe do IDE, vytvořím persistence.xml, který volá pomocí JNDI spojení s MySQL, kterou jsem v glassfish konsoli vytvořil.
Pro namapování relačních tabulek do JPA využiji požnosti IDE a nechám si je automaticky vygenerovat. Pro snadou správu samotných dat, vytvořím na klientovi nějakou CRUD aplikaci, takže si nechám vygenerovat i Session Beans z JPA. Použiji jak lokální, tak remote interface. Po tomto kroku, mám základ připraven. Mohu provést deploy na glassfish.
Nyní se pustím do samotného klienta. Nejprve desktopu. Vytvořím si samostatný projekt, do kterého nalinkuji potřebné glassfish knihovny a přilinkuji samotnou business logiku ve formě jar souboru. Pomocí vzdáleného volání, si nechám zavolat Session Beanu a již rovnou mohu pracovat s business logikou ve Swingu. K samotné distribuci swingové aplikace použiji Java Web Start.
Poslední věcí je webová aplikace. Přilinkuji JSF Framework, společně s Facelets. V Backing Beans volám Local EJB. Webová aplikace je v tomto ohledu o dost jednodušší, jelikož nemusím řešit vzdálené volání EJB, protože samotná aplikace běží na glassfish ve webovém kontejneru. Samozřejmě nezapomenu na convertery pro Entity a nastavení, jako navigaci, atd. Webovou aplikaci mohu vystavit na server.
Asi takto bych zjednodušeně popsal samotnou problematiku Enterprise Javy. Jako IDE jsem zvolil NetBeans a k deploymentu aplikací chytrého mravence (ant).
Tímto článkem jsem chtěl jen nastínit, že s PHP končím. Od dnešní doby se budu věnovat Javě či databázím. Pokud je někdo v podobné situaci jako já, přivítám jeho připomínky.
Na začátku je důležité si zvolit správnou technologii. Pokud zvolím Javu budu muset řešit další věc a tou je její ohromné množství frameworků. Osobně jsem toto vyřešil tak, že se držím (pokud je to jen možné) standardů SUNu.
Takže co je cílem: Vytvořit intranetovou aplikaci, která bude pokrývat požadavky firmy. Od výrobních procesů, přes ekonomické záležitosti až po různé schvalovací procesy. Klientem bude webová či desktopová aplikace. Ve chvíli, kdy potřebuji komunikovat se sériovým portem, musím volit desktop. Když budu řešit výpis sestav, použiji zase webovou aplikaci. Obě tyto aplikace musejí míti stejnou základnu (databázi). V lepším případě základnou bude business logika pro obě aplikace.
Jak jsem psal výše, zvolil jsem nejpoužívanější frameworky, které jsou navíc i standardy. Na persistenci (připojení k databázi) TopLink od Oracle. Jako databázi MySQL 5.0. Na namapování relačních tabulek do objektů JPA. Samotná business logika je řešena přes EJB3.0. Na webovou část jsem zvolil JSF společně s Facelets (i když Facelets není standard, dost pomáhá samotnému JSF). Na desktop Swing. Aplikační server je Sun Java Application Server 9 (glassfish).
Takže zvolené součásti mám úspěšně za sebou. Nyní přistoupím k samotné implementaci. První věcí, kterou musím udělat, je rozjet MySQL v glassfish. Toto udělám jednoduše tak, že nahraji java-mysql-connector do adresáře PATH_GLASSFISH/lib. V samotné admin konsoli (webová aplikace pro správu glassfishe), vytvořím connection pool a jdbc resource pro mysql a danou databázi.
Nyní přistoupím k tvorbě business logiky. Po vytvoření enterprise projektu ptovedu vytvoření persistence pomocí TopLinku. Po namapování glassfishe do IDE, vytvořím persistence.xml, který volá pomocí JNDI spojení s MySQL, kterou jsem v glassfish konsoli vytvořil.
Pro namapování relačních tabulek do JPA využiji požnosti IDE a nechám si je automaticky vygenerovat. Pro snadou správu samotných dat, vytvořím na klientovi nějakou CRUD aplikaci, takže si nechám vygenerovat i Session Beans z JPA. Použiji jak lokální, tak remote interface. Po tomto kroku, mám základ připraven. Mohu provést deploy na glassfish.
Nyní se pustím do samotného klienta. Nejprve desktopu. Vytvořím si samostatný projekt, do kterého nalinkuji potřebné glassfish knihovny a přilinkuji samotnou business logiku ve formě jar souboru. Pomocí vzdáleného volání, si nechám zavolat Session Beanu a již rovnou mohu pracovat s business logikou ve Swingu. K samotné distribuci swingové aplikace použiji Java Web Start.
Poslední věcí je webová aplikace. Přilinkuji JSF Framework, společně s Facelets. V Backing Beans volám Local EJB. Webová aplikace je v tomto ohledu o dost jednodušší, jelikož nemusím řešit vzdálené volání EJB, protože samotná aplikace běží na glassfish ve webovém kontejneru. Samozřejmě nezapomenu na convertery pro Entity a nastavení, jako navigaci, atd. Webovou aplikaci mohu vystavit na server.
Asi takto bych zjednodušeně popsal samotnou problematiku Enterprise Javy. Jako IDE jsem zvolil NetBeans a k deploymentu aplikací chytrého mravence (ant).
Tímto článkem jsem chtěl jen nastínit, že s PHP končím. Od dnešní doby se budu věnovat Javě či databázím. Pokud je někdo v podobné situaci jako já, přivítám jeho připomínky.
Příště se již budu věnovat něčemu přímočarému. Ukážu, jak ve stand-alone klientovi volat EJB z glassfishe. Na konci celý projekt zbuilduji a nechám poskytovat pomocí Java Web Start.
Přihlásit se k odběru:
Příspěvky (Atom)
Když programátor založí a řídí firmu
Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...
-
Každý, kdo chce efektivně pracovat s objekty, musí použít nástroj, který mu umožní automaticky doplňovat potřebné informace. Jinými slovy, p...
-
Minule jsem psal o možnosti spojení Wicketu s EJB3 a o Wicket Security. Dnes se podívám na další vlastnosti a možnosti tohoto webového frame...
-
Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...