Abstrakce použití webové aplikace

Jak se používají dnešní webové aplikace? Mnozí uživatelé asi odpoví, že se do aplikace nejprve registrují, přihlásí se a pak v aplikaci naleznou příslušnou stránku, na které vyplní formulář a odešlou ho na webový server. Tuto činnost provádějí tak dlouho, dokud neukojí svých potřeb. Samozřejmě, každý vývojář se s podobnou výpovědí setkal a zná ji ze své praxe. Představí si ji asi tak, že aplikace bude disponovat

  • registračním formulářem na stránce s registrací,
  • přihlašovacím formulářem na hlavní stránce,
  • a stránkami s jinými formuláři na jiných stránkách.

Taková představa je ovšem trochu urychlená, protože se váže na implementační detaily a především na návrh uživatelského rozhraní. V takovém znění by měla zajímat spíše koncového uživatele. V základních fázích vývoje webové aplikace nás vývojáře nebude zajímat rozvržení jednotlivých stránek ani jaké zvolit prvky do formulářů. Takové rozhodovaní odložíme na později. Zkusme se na to podívat z jiného úhlu a pojďme se nyní zamyslet nad vhodnou abstrakcí použití naší aplikace koncovým uživatelem.

Uživatel přistupuje k aplikaci vždy s nějakým záměrem, tzn. že chce, aby vykonala něco v jeho zájmu. Interakci uživatele s webovou aplikací za určitým cílem budeme označovat jako případ užití (anglicky use case). Případy užití můžou být podmíněny rolí uživatele (např. jen administrátor může měnit zásadní nastavení) nebo jinou výchozí podmínkou (např. zákazník musí mít v košíku nějaké zboží, aby mohl potvrdit objednávku) a často jsou variabilní (např. aby mohl uživatel změnit počet konkrétního zboží v košíku, musí být zboží dostupné na skladě). Důležitým faktem je, že webová aplikace disponuje konečným počtem případů užití.

„Referenční příručka jazyka UML definuje případ užití jako specifikaci posloupností činností, včetně proměnných posloupností a chybových posloupností, které systém, podsystém nebo třída může vykonat prostřednictvím interakce s vnějšími aktéry.“ [USDP, strana 95]

Metodika Unified Software Development Process zaznamenává případy užití pomocí diagramů případu užití notačního jazyka UML. Ačkoli jazyk UML nepředepisuje konkrétní způsob textové specifikace, je ustálen zápis pomocí šablony [USDP, strana 99]. Na úrovni lidské řeči (pseudokódu, chcete-li) jsou zaznamenány veškeré možné použití aplikace koncovým uživatelem. Ptáte se k čemu to je dobré? Stačí prý naházet do šablon několik formulářů, provázat je controllery a nějak to napojit na databázi? Ten pravý důvod na nás stále čeká!

Webovou aplikaci lze zjednodušeně definovat jako model a uživatelské rozhraní postavené nad modelem, které koncovému uživateli umožňuje s modelem komunikovat a manipulovat a tím realizovat případy užití. Velmi často je ve webových aplikacích externí uživatel v rámci modelu reprezentován a jako interní entita komunikuje se zbylou částí modelu.

Návrh případů užití spočívá v transformaci modelu na úrovni lidské řeči (požadavků na webovou aplikaci) do modelu na úrovni komunikace objektů našeho modelu z MVC. V UML lze tuto komunikaci zachytit pomocí sekvenčních diagramů (je možné využít i další diagramy). Tím docílíme popsání úplné funkčnosti modelu.

V rámci otázky implementace nás bude držet při zemi databáze jakožto úložiště dat. Naštěstí je možné postavit model na nějakém ORM a částečně se s nástrahami vypořádat. Teď, když už máme čistě objektový perzistentní funkční základ webové aplikace, který je schopný obstarat všechny případy užití externích uživatelů, je teprve čas na natlačení uživatelského rozhraní do controllerů, šablon a formulářů!

[USDP]Jim Arlow, Ila Neustat: UML 2 a unifikovaný proces vývoje aplikací, Computer Press, 2007

štítky: , ,

K něčemu malému s velkou myšlenkou

Byl jsem zendařem. Už je tomu asi rok a půl zpátky. Hledal jsem vhodný PHP framework, který by mi ulehčil práci při psaní webových aplikací. Tenkrát jsem se rozhodl pro Zend Framework hlavně z toho důvodu, že ho vyvíjeli autoři PHP. Říkal jsem si, že asi bude psán kvalitně. Výběru napomohla také skutečnost, že frameworků tenkrát ještě moc nebylo, nebo o nich aspoň nebylo tolik slyšet. To až v poslední době se s nimi roztrhl pytel. Pamatuji si, byla to verze 1.5, kterou jsem začal studovat. Naivně jsem si vytiskl celou dokumentaci. To se ještě vešla na pouhých 670 stránek. K tomu jsem si koupil knihu, která se vázala k verzi 1.5, a začal jsem se vzdělávat.

Přechod na verzi 1.6 byl jediný přechod, který jsem stihl plně pochytit. S přechodem na verzi 1.7 mi toho hodně proklouzlo a další přechody už jsem sledovat nestíhal. Zend Framework byl hodně rozšířen do všech směrů a stalo se z něho obrovské neovladatelné monstrum. Kde zůstala ta základní kostra verze 1.5? S vytisknutou dokumentací a zakoupenou knihou si teď můžu tak akorát tak… Nezastavitelný bezmyšlenkovitý vývoj mě začal na frameworku vadit. To když začínáte s projektem na aktuální verzi frameworku, museli byste projekt před dokončením pořád upravovat na tu novou a novou verzi, abyste jeli pořád na té aktuální. Framework má přece práci ulehčovat, ne ztěžovat. Občas se najdou i celkem zásadní změny jako např. psaní bootstrapového souboru pomocí objektu třídy Zend_Application nebo třeba zavedení URL helperů. Podle mého názoru by takové věci měly být stanoveny před počátkem vývoje frameworku. Jsou to základní kameny, na kterých by se mělo začít stavět. Kromě toho mě odradila rychlost frameworku. Je samozřejmé, že se to nabalování nových vlastností muselo někde projevit. Jednoduše Zend Framework už nesplňuje moji ideologii frameworku. Netuším, proč se vývojáři snaží, aby uměl úplně všechno.

V tomto ohledu se mi zalíbil Nette Framework, který mi byl doporučen Tomášem Jukinem. Má totiž jasně vytyčenou myšlenku, se kterou ho David Grudl píše. Fascinující je, že je framework vyvíjen pouze jediným člověkem, který si dle vlastního uvážení řekne, ano, tohle tam dám nebo ne, tohle si tam dodej sám! Líbí se mi, že se framework nerozrůstá do maximálních rozměrů a zůstává jednoduchý, jasný a srozumitelný. Mimo to využívá rozhraní a kvalitního objektového přístupu. Další plus u mě získal tím, že nemá knihovnu pro práci s databázi a tak si v klídku můžu dodat mnou zvolený ORM nástroj a stavět na něm celý model. I když mám s tímto frameworkem zatím více méně nulové zkušenosti, tak splňuje moji ideologii frameworku a vypadá to, že budeme kamarádi!

Chtěl jsem vám jenom oznámit, že přecházím od něčeho velikého s malou myšlenkou k něčemu malému s velkou myšlenkou, od Zend Frameworku k Nette Frameworku.

Příjem, nahrávka, smeč, kdo že to chytá křeč?

Napíšu ještě jednu větu? Ne, to už jí musí stačit, říkal jsem si při dopisování klauzury z fotomédií při posledních dvou pátečních hodinách. Kolena se mi třásla a radostí jsem mlátil rukou do stolu. Těšil jsem se totiž na tak dlouho očekávaný volejbalový turnaj v Heidenau. Po škole jsem zametl náš internátní pokoj (už taky bylo na čase), připravil ležení pro starší část našeho týmu a s napětím je vyčkával. Dorazili v následujícím složení: Luďa, taťka, Tomík, Michal a Bára. Ještě s Petrou a Durym jsme vytvořili tým chmelařského města Žatec s názvem Hopfenstadt Saaz. Už před intrem na nás vytáhli všelijaké nádoby různých tvarů a hlavně obsahů, odnesli si zavazadla a pak se razilo na nádraží. Nejprve byli všichni zmatení a to samé říkali o mně, ale na nádraží jsme úspěšně trefili. Představili jsme jim komfort německých lokálek a pak jsme si to štrádovali z heidenauského (nebo jak by se to jinak dalo říct) nádraží do tělocvičny. Mapy se sice chopila Petra, ale i tak jsme na osudové místo dorazili.

Volksbank Cup

Volksbank-Cup 2009

Převlékli jsme se do tmavých dresů s červeným nápisem a logem přeškrtnutých čar, symbolizujících pivní účet. Po registraci jsme se ocitli v základní skupině s jedním z našich školních družstev, družstvem pana Molína a dalším, neznámým, družstvem. Turnaj byl vymyšlen podle mého názoru hodně nerozumně. Zápas se hrál totiž 1×8 minut a tak než jsme se stačili rozkoukat, byl už konec. To ale nic nemění na tom, že jsme základní skupinu vyhráli a porazili Piranhu, družstvo kterému šéfuje pan Molín. Po odehrání posledního balónu Michalovo medvědí tlapou a následné kruté bouchnutí o zem způsobilo hřejivý pocit uvnitř celého mého těla. Tím byl splněn první z mých cílů. Po stálém doplňování tekutin a dalších zápasech jsme splnili i můj druhý cíl, a to, postoupit a přesunout se do druhé tělocvičny. Trochu mě štvalo, že Rocco, který hrál za Lokotku a začínal v druhé hale, nepostoupil a hrál o útěchu v naší začáteční hale, takže jsme si haly vystřídali.

Říkal jsem si, že hala, ve které se bojuje o první místo, se musí mít k světu, ale trochu jsem se zmýlil. V hale sice byla tribuna a geniální sprchy na žetony (na jejichž princip jsem prostě nepřišel a tak jsem musel nenápadně vlézt do Duryho sprchy), ale síť byla nízko a ještě prověšená. A k tomu na ní nebyly antény. Prostě z technické stránky jednoznačné zklamání. Nechme tyto věci ležet, vždyť síť byla na obou stranách stejná. Zkuste se zamyslet nad tím, s jakou pravděpodobností lze uhrát v zápase na 8 minut remízu. A ještě když 40 vteřin před koncem držíte náskok o tři body. Neměli jsme štěstí a hráli jsme dál o 7. místo. Kozlíci to na nás už zkoušeli s jejich umělohmotným – více méně vietnamským – míčem, ale my jsme se nedali a poslali je zpět do receptáře. V rozhodujícím zápase jsme už nebyli dostatečně motivováni a možná trochu zapracovali nervíci a tak jsme se umístili na (myslím si) krásném 8. místě z celkových 28 družstev (přítomných jich bylo jen 26, to je jenom, aby to vypadalo). O školních družstvech jsem neměl ani páru, protože se s námi do jiné haly nepřesouvali a hráli v druhé hale o 13. místo. Piranha se po finálovém boji s bezejmennými umístila na druhém místě. Takže se můžeme těšit z toho, že jsme porazili tým na 2. i na 3. místě. Své očekávání jsem splnil, ale až za rok jim teprve ukážeme, jak se to hraje. Třeba budeme mít i kapku toho štěstí, které jsme letos docela postrádali.

Tím to ale (naštěstí/bohužel) nekončilo. Petra odjela s Petrem a my se vydali zpátky na intr. Mysleli jsme, že to na návsi (rozuměj náměstí) bude žít, ale žilo to pouze přípravou pódia, tak jsme zalezli k Turkovi do Kebap Hausu. Tomík nám ukázal základy stolování a po tom, co měl sósu úplně všude, si sedl a začal nás nenápadně tahat domu. Jak jinak by se dalo vysvětlit, že jsme měli 4 účty? Celková suma byla víc než solidní, ale i tak byl Tomík připraven si to u Turka nebo Turkyně odpracovat. Turek z nás už byl trochu na větvi a tak jsme to kolem druhý zalomili. S troškou rámusu jsme se vrátili na intr a tam byl teprve srandy kopec. Bitva o postele, krapet hudby a Tomíkovo mírné upouštění. Tyto činnosti naplňovali naší zábavu před tím než jsme ulehli. Pak už bylo slyšet jen řezání motorové pily… Nejlepší zjištění ale bylo, že Dury, který měl vstávat v 6 hodin kvůli závodům v pádlování, zaspal!

štítky: ,

Bootstrap file a nekoncepční třída

K tomuto příspěvku mě dotlačilo toto téma na českém ZF fóru, ale především tři noci prosezené u psaní a konečné formulace bootstrap file pro projekt My Town Game, o kterém vám v blízké době povím něco více. Zakrývám si oči pravou rukou, otáčím se a ulehám do kouta. Harvejsi, měl jsem bootstrap tak veliký a nepřehledný, že jsem byl donucen ho přepsat do nekoncepční třídy s originálním názvem Application. Kromě tebou zmiňované přehlednosti má nekoncepční třída bootstrap filu ještě takovou výhodu, že se u každé metody dá napsat pěkný phpDoc komentář, který mi vždy připomene, co že se to teď vlastně louduje. Takže se ti předem omlouvám a nedivím se, proč je kolem vývoje třídy Zend_Application takové vzrůšo. Dovolil bych si tedy tvrdit, že pokud se jedná o větší ZF projekt, jehož bootstrap file by byl v základním znění nepřehledný, je výhodné, naházet to všechno do nekoncepční třídy. Musím tedy přihmouřit své OOoči… ;-)

Ehm, a co že to ta nekoncepční bootstrap třída vlastně je? Představte si, že váš bootstrap file index.php (www/index.php) bude vypadat následovně a že statická metoda s divokým názvem run() se postará o všechno, co je třeba:

1
2
3
4
5
// include class Application
require_once '..' . DIRECTORY_SEPARATOR . 'application' . DIRECTORY_SEPARATOR . 'Application.php';

// execute the application
Application::run();

Přesuneme se dále do třídy Application (application/Application.php), která implementuje návrhový vzor singleton, protože aplikaci přece nebudeme spouštět vícekrát najednou, a to i kdyby měla Sofie S. zůstat sama samotinká. Tato metoda potom ve zkratce zavolá po sobě seřazenou většinu loudovacích metod, které jsou ve třídě dostupné. To je kalibr!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * This method execute the application
 *
 * @return void
 */

public static function run()  {

    self::getInstance()->_setErrorReporting(); // error reporting level
    self::getInstance()->_setDefaultTimezone('Europe/Prague'); // default timezone
    self::getInstance()->_setApplicationDir(); // application directory
    self::getInstance()->_setIncludePath(); // include path
    self::getInstance()->_registerAutoload(); // autoloader
    self::getInstance()->_netteDebug(); // Nette debug
    self::getInstance()->_loadConfig(); // loading configuration
    self::getInstance()->_initCache(); // cache
    self::getInstance()->_doctrineConnect(); // database connection
    self::getInstance()->_initRouter(); // router
    self::getInstance()->_initFrontController(); // front controller
    self::getInstance()->_dispatch(); // dispatch

}

Všechny takto volané metody jsou soukromé a vykonávají část bootstrap funkcionality, která se takto dá velmi jednoduše dokumentovat pomocí phpDoc u každé této metody a samozřejmě také rozšiřovat novými metodami. Třída pak může obsahovat ještě pomocné soukromé metody nebo veřejné metody pro přístup z pluginů nebo z controllerů. Na ukázku ještě detail metody pro připojení do databáze:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Doctrine lazy database connection
 * It creates a connection string by class Tools_Doctrine and it forwards this string
 * to Doctrine manager.
 *
 * @link http://www.doctrine-project.org/Doctrine_Manager/1_0#method_connection
 * @see class Doctrine_Manager
 * @see class Tools_Doctrine
 * @return void
 */

private function _doctrineConnect() {

    $connection = Tools_Doctrine::getConnectionString($this->_config->database);
    Doctrine_Manager::connection($connection);
    $connection = null;

}

No a konečně disponuje nekoncepční bootstrap třída výhodou, že si může všechno zapamatovat ve svých členských proměnných a o použití Zend_Register si můžete nechat během teplých letních nocích jen zdát. Následující kód zobrazuje příklad deklarace členských proměnných.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
 * Single instance of class Application
 *
 * @staticvar Application
 */

private static $_instance = null;

/**
 * Application directory
 *
 * @var string
 */

private $_dir = '';

/**
 * Configuration object
 *
 * @var Zend_Config
 */

private $_config = null;

/**
 * Cache object
 *
 * @var Zend_Cache
 */

private $_cache = null;

/**
 * Router
 *
 * @var Zend_Controller_Router_Rewrite
 */

private $_router = null;

/**
 * Language
 *
 * @var string
 */

private $_language = '';

/**
 * Application locale
 *
 * @var Zend_Locale
 */

private $_locale = null;

/**
 * Translation object
 *
 * @var Zend_Translate
 */

private $_translator = null;

/**
 * Instance of Front Controller
 *
 * @var Zend_Controller_Front
 */

private $_frontController = null;

Vše co je libo je prostě přístupné a tak si ještě nakonec shrneme výhody a nevýhody nekoncepční bootstrap třídy. Mezi výhody patří:

  • přehlednost
  • dokumentovatelnost
  • rozšiřovatelnost
  • přístupnost
  • znovupoužitelnost

A mezi nevýhody patří:

  • nekoncepčnost
  • rychlost (zanedbatelná)

Stejně jako jsem v článku o kategorizaci přístupu k tvorbě PHP projektu neodsuzoval žádný z přístupů, tak ani v tomto případě netvrdím, že některý způsob tvorby bootstrap filu je obecně nejlepší. Proč si myslíte, že to Zend Framework nechává otevřené a předává tuto starost na samotné programátory?

Tak už si mě odvezli

Ano, je tomu tak. V pátek se mi celý den motala hlava a večer před spaním jsem měl pocit, že se nemůžu nadechnout. Nasadil jsem si tedy půlku kalhot a vyšplhal se do bytu paní Pokorné. Do nemocnice jsem se se Slayem projel sanitkou. Uvítali mě a provedli pár základních vyšetření. Mimo to mi do pravé ruky zasadili speciální lidské rozhraní API, se kterým jsem komunikoval s infuzemi. Když mi dělali ultrazvuk, Slay při pohledu na flekatý displej s úžasem povídal: „Vidíš, bude to chlapeček.“ Chlapci ze mě byli nejprve trochu zmatení, ale nakonec mě uložili do jedné z postelí.

Takový luxus a komfort, který jsem tam zažil, se celkem nedá srovnávat. Místo obyčejného lůžka jsem ovládal letecký simulátor a hodnoty letu se mi zobrazovali na parádní minitelevizi s rádiem. Jídlo se internátnímu také vůbec nevyrovnalo, všechno mi tam chutnalo. Během pobytu mě sice občas vyrušil nějaký ten doktor, který si na mě chtěl šáhnout, nebo mě odvedli na nějaké to vyšetření, ale stejně jsem měl na programu nejčastěji spánek. Programovat jsem bohužel mohl jen na papír, ale i tak to stálo za to. Celkem často se u mě střídaly návštěvy z intru, tak jsem si poslechl aspoň trochu češtiny. Mimo to, ty mladé sestřičky…

No a v předposlední den mé nemocniční rekreace přivezli Goga, který se snažil napodobit Angeliku při chůzi po schodech. Vyvrknul si kotník a při sjezdu následujícího schodiště udělal 3 salta a 5 vrutů. Jenže jeho připojili do Matrixu. Vedle sebe měl speciální oscilátorový přístroj, který měřil, jak často dýchá. No a to by to nebyl Gogo, kdyby ty ladné křivky jeho dechu neupravoval a neukazoval všem. Nejlépe mu odpověděl pan Molín: „Filipe, až se budete umět podepsat, to bude teprve něco.“ A Gogo hned začal trénovat.

Sice jsem po příjezdu trochu unavený z toho odpočívání a ruce mám jako feťák, ale řeknu vám jedno, kdyby tam měli internet, tak už mě odtamtud nedostanou!

štítky: