S objekty do světa

Musím se přiznat, že jsem na prvním ročníku konference WebExpo postrádal přednášku o pravém objektovém programování webové aplikace. Smutnil jsem, že se žádná významná osoba touto problematikou nezajímala. Postupem času jsem si začal uvědomovat zatemnění především začínajících vývojářů při neúplném pochopení architektury MVC a především zanedbávání modelu, který byl často nahrazován databázovými dotazy přímo v controllerech. Pořekadla jako Model je funkční základ aplikace.“ nebo Na model lze napasovat několik různých UI.“ se řadili pouze mezi teoretické poučky.

Podobný problém zaznamenal i Tomáš Jukin a tak jsme se rozhodli vyrazit s objekty mezi lidi. Na letošním WebExpu si v rámci našeho workshopu Vývoj objektových webových aplikací v PHP metodikou USDP pomocí UML povíme, že vývoj webových aplikací na základě bezhlavého psaní kódu už dnes neletí. Vysvětlíme si, jak efektivně modelovat webové aplikace pomocí objektové metodiky Unified Software Development Process a jako jednotný dorozumívací jazyk v rámci vývojového týmu (popř. přímo s klienty) používat UML. Nad obyčejný podřadný kód posadíme abstraktní rovinu, která nám pomůže udělat si obrázek o systému mnohem rychleji než marné orientování v kódu. Značnou výhodou hotové aplikace bude její velmi dobrá upravitelnost a rozšiřitelnost.

Náš 3,5 hodinový workshop se koná v sobotu 17.10.2009 časně zrána. Workshop bude rozdělen do dvou částí. Nejprve si povíme něco málo nezábavného o teorii modelování informačních systémů, metodice Unified Software Development Process a notačním jazyku UML. V druhé části vás provedeme řízením reálného projektu na základě metodiky USDP. Budeme si hrát na vývojový tým a společnými silami vyvineme použitelnou objektovou webovou aplikaci. Účastníci si v rámci workshopu vyzkouší CASE nástroj Enterprise Architect, získají teoretické základy metodiky USDP a jazyka UML a pochopí jak správně nakládat s modelem z architektury MVC na reálném příkladu založeném na technologiích Nette Framework a Doctrine. Pište správné objektové webové aplikace a bude se vám lépe usínat!

Asociace typu M:N

Rozhodl jsem se publikovat první technicky založený článek. Mapování objektů do relační databáze je pro dnešní objektové jazyky občas oříškem. Největší neplechu páchá asociace typu M:N. Ta není dnešními objektovými jazyky přímo podporována. V tomto článku přiblížím, jak úspěšně vysvětlit objektovým jazykům, že hvězdičky můžou svítit na obou stranách.

Cože to vlastně ta asociace typu M:N je? Každý se s ní už určitě setkal. Na diagramu 1 je zobrazen jednoduchý příklad. Učitel může vyučovat několik žáků z různých tříd a zároveň každý žák může být vyučován několika různými učiteli. Dokážu si představit, že obě analytické třídy budou nahrazeny návrhovými třídami a že hodnoty atributů budou uloženy ve dvou tabulkách relační databáze. Ve fázi analýzy je na tento diagram radost pohledět, jenže ve fázi návrhu už tak růžově nevypadá.

Diagram 1: Asociace typu M:N ve fázi analýzy

Diagram 1: Asociace typu M:N ve fázi analýzy

Podívejme se nyní do pozdější fáze analýzy, co se s naší školskou delegací stalo. Na diagramu 2 jsou vidět doplněné atributy a operace. Jen objasním, že operace zjistiSeznamZaku() vrací asociativní pole všech objektů typu Žák, které daný objekt typu Učitel vyučuje. Na opačné straně vrací operace zjistiSeznamUcitelu() asociativní pole všech objektů typu Učitel, které vyučují daný objekt typu Žák. Některé jazyky místo pole používají kolekce objektů, tím už se ale náš článek nezabývá. Ostatní atributy a operace popisovat nemusím, protože jsem zvolil opravdu jednoduchý příklad.

Diagram 2: Asociace typu M:N s atributy a operacemi tříd

Diagram 2: Asociace typu M:N s atributy a operacemi tříd

Přenesme se nyní mezi řádky nějakého skriptu, který vypisuje ke každému učiteli všechny vyučované žáky. Pokud by se databáze sestávala pouze ze dvou tabulek, jako je vidět v diagramu 3, budou nám stále chybět reference mezi jednotlivými objekty typů Učitel a Žák a náš skript, ať už bude sepsán jakkoli, náš cílený problém nevyřeší a nedokáže ke každému učiteli vypsat všechny jím vyučované žáky. Příklad tabulek je v MySQL.

Diagram 3: Pohled na zamýšlené databázové tabulky

Diagram 3: Pohled na zamýšlené databázové tabulky

Takže nám něco chybí. Pojďme se zbavit té ohyzdné asociace typu M:N a rozbijme ji na dvě asociace typu 1:M. Vložme mezi asociaci typu M:N jednu třídu navíc, kterou můžeme pojmenovat speciálním názvem například Výuka nebo jednoduše spojením názvů obou spojovaných tříd, tzn. UčitelŽák. Tato geniální třída bude sloužit jako pojítko mezi našimi třídami. Každá instance bude ukazovat právě na jeden objekt typu Učitel a právě na jeden objekt typu Žák. Jako celek jsem určil třídu Učitel z toho důvodu, že budeme vypisovat žáky, které učitel vyučuje. Objekty typu Učitel jsou tedy odpovědné za životní cyklusy objektů typu Výuka. Stejně tak bychom mohli třídu Výuka přiřadit třídě Žák. Výsledek je zobrazen na diagramu 4.

Diagram 4: Využití propojující třídy Výuka

Diagram 4: Využití propojující třídy Výuka

Na diagramu 5 jsou zobrazeny tabulky relační databáze, které jsou nyní propojené přes cicí klíče (foreign keys) tabulky Výuka.

Diagram 5: Pohled na konečné tabulky databáze

Diagram 5: Pohled na konečné tabulky databáze

(pozn. děkuji maartymu za upozornění komentářem, že EA umí modelovat databáze…)

Metoda zjistiSeznamZaku() nyní vybere z tabulky Výuka veškeré řádky, u kterých je idUcitele rovno id hledaného učitele. Metoda vytvoří pole objektů typu Žák, jejichž id se nachází v nalezených řádcích v tabulce Výuka. Toto pole nakonec vrátí. Již zmiňovaný skript nyní může pole projít a vypsat jméno a příjmení.

Tak jsme si osvětlili, jak se manuálně vypořádat s asociací typu M:N. Nad relačními databázemi dnes ale existují ORM nástroje, které se s asociací typu M:N vypořádají automaticky a programátor ani nepocítí, že se v databázi nachází ještě nějaká propojovací tabulka. Takový ORM nástroj pro PHP je například Doctrine, který je inspirován Hibernate pro Javu.

štítky: , ,