pátek 28. září 2007

NetBeans Platform (díl 2) – Výhody a nevýhody

Důvod, proč jsem zvolil desktop aplikaci vznikl z požadavku vytvořit aplikaci, která by komunikovala přes sériový port a ukládala čísla karet z různých čteček. Moc možností na výběr jsem neměl, jelikož přes webové rozhraní bych nebyl nic takového schopen aplikovat (samozřejmě nebudu zohledňovat aplety, které se mi dost příčí).

V první fázi jsem zvolil vlastní řešení (jako správný PHPčkář), přes Swing. Vše bylo v pořádku, do doby, kdy se aplikace začala rozrůstat. Implementace jednotlivých částí se prostě příliš svazovala mezi sebou a já začal mit v aplikaci chaos. Příčinou je jednak má nezkušenost s podobným druhem aplikací a jednak pouhá okrajová znalost konceptu pro distribuovanou Javu.

Poté jsem zajel na JAG, ve kterém se probírala RCP aplikace (NetBeans vs. Eclipse) a já si uvědomil, kde dělám chybu a jaké jsou výhody těchto řešení.

Asi bych měl znovu uvést, že se jedná o platformu, jinými slovy o „podvozek“, na kterém může běžet cokoli. Nejčastěji je ovšem známá kombinace: platforma + IDE = NetBeans IDE, Eclipse IDE. Dalo by se říci, že samotné vývojové prostředí je pouhý plugin dané platformy, i když je asi nejvýznamějším pluginem obou platforem.

Nyní již k samotným výhodám a nevýhodám tohoto řešení, do kterého zahrnuji kompletní řešení včetně použití dané platformy:

Z pohledu typu aplikace (desktop aplikace)

Výhody:
- možnost vytvořit přívětivé prostředí pro uživatele
- schopnost asynchroního volání bez zásahu nějakých zvláštních featur
- rychlá odezva mezi uživatelem a serverem
- prostředí umožňující přímou vazbu mezi uživatelem a OS (komunikace s periferiemi daného klientského PC)
- uvnitř desktop aplikace možnost používat i webovou aplikaci (vlastní web browser)

Nevýhody:
- distribuce (sice existují řešení jako JWS, ale s web aplikací se to srovnávat nedá)
- instalovana Java na klientském PC
- jisté systémové požadavky na běh aplikace (velikost RAM, atd)


Z pohledu architektury aplikace

Výhody
- swing (funguje kdekoli i s událostmi, na rozdíl od javascriptu u web aplikací)
- modulární systém (platforma stojí na tomto principu, který extrémně zpřehledňuje vývoj aplikace)
- skutečné OOP bez nutnosti statických view (HTML)
- Lookup (jedná se o hledání „služeb“ uvnitř kontextu NetBeans RCP)
- Services (služby, které lze registrovat a pomocí nich kominukovat mezi jednotlivými moduly, kteří o sobě vůbec nevědí, nemusí byt na sebe vázány)
- NetBeans API (při využívání tohoto API si navíc dokáži usnadnit práci a přímo ovlivňovat chování aplikace bez nutnosti přímého psaní swing komponent)
- podpora pluginů (pokud ve své aplikaci potřebuji nejakou funkčnost, kterou obsahuje plugin napsaný třetí stranou, mohu ho klidně využít a ušetřit si práci)
- celý koncept platformy, který je navržen tak, aby nejlépe odpovídal potřebám při psaní uživatelsky přívětivé aplikace

Nevýhody:
- náročná studie celého NetBeans API
- vzdálené volání EJB (spousta problémů při prvním setkání)
- v mnoha případech se jedná o kanón na vrabce

Asi by se dalo nalézt více kladů či záporů, ale v mém osobním pohledu, spatřuji tyto vlastnosti jako nejzásadnější.

V současné době se navíc musím vrátit k web aplikaci (osobně volím JSF), jelikož stojím před neřešitelným problémem: distribuce aplikace, s tím spojená i přímá aktualizace aplikace; a hardwarová náročnost aplikace, která mi neumožňuje distribuovat aplikaci mezi uživatele (velké fabriky holt nemají zájem tolik investovat do informatiky, kterou asi považují za nepotřebný subjekt).

I přes tuto velkou bariéru, mohu pokračovat na obou klientských verzích. Jak desktop, tak web, jelikož business logika (EJB kontejner) zůstává pro obě řešení stejná.

úterý 28. srpna 2007

NetBeans Platform 1. - Úvod

O co půjde?

Již podle názvu je jasné, že jsem se rozhodl psát o samotných NetBeans jako o platformě. V současné době se věnuji vývoji aplikace postavené právě na tomto "podvozku", a proto s tím souvisí i má snaha získat co nejvíce informací a zkušeností s touto platformou.

Předem bych rád upozornil, že nejsem žádný specialista v oblasti RCP aplikací, a proto se spíše budu zabývat menšími oblastmi při vývoji.

Často se mi stávalo, že jsem se v některé z pasáží natolik zasekl, že mi trvalo i několik dní, než jsem přišel na správné řešení. Jelikož jsem člověk, který rád pomáhá druhým, rozhodl jsem se, že touto formou pomohu některým lidem při jejich potížích.

Sám se budu snažit o zpětnou vazbu a pokud někdo bude znát lepší způsob implementace dané věci, budu rád, když ji poskytne ostatním.

Co byste si měli přečíst...

Jak už to tak bývá, tak i zde je třeba někde začít. Jistým předpokladem je znalost Javy, základní znalost swingu a znalost používání NetBeans jako vývojového nástroje.
Pokud všechny tyto znalosti mám, mohu se pustit do vývoje. Osobně jsem začal krátkými tutoriály na www.netbeans.org/, poté by měla být na řade kniha Rich Client Programming: Plugging into the NetBeans Platform.
Následuje Geertjan's Weblog, který popisuje jednotlivé postupy a nabízí srozumitelnější výklad než samotný javadoc.

Další zdroje se dají samozřejme nalézt pomocí googlu či na stránkách netbeans.org. Já se zaměřím spíše na základní popis.

NetBeans RCP

NetBeans IDE

Jako základní API jsem si zvolil NetBeans 6.0 M10. I když se jedná pouze o milestone, domnívám se, že se až tolik změn v API konat nebude. Proto všechny příklady budou předpokládát, že máte tuto verzi, či verzi vyšší, nainstalovánu.
Jelikož je spousta komponent přímo svázána (děděno z komponent Swingu ) se swingem, nebudu se příliš zaobírat jejich funkčností a budu předpokládat základní znalost těchto komponent.


Nakonec bych ještě jednou rád podotkl, že ne všechna řešení jsou v souladu se spravným použitím. Dost často se může stát, že bude existovat novější, efektivnější či odlišný způsob řešení daného problému. Proto mě prosím nekamenujte za tyto postupy, ale raději se pokuste přispět svými nápady v diskuzi.

NetBeans IDE

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:

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

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

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.

V příštím díle ukáži, jak po instalaci nakonfiguruji základní parametry pro chod daných produktů.

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