\section{Úpravy prezentační vrstvy}
\label{sec:upravyprezentacni}

\secpreview{Tato kapitola blíže rozebírá úpravy prezentační vrstvy.
  Oddíl~\ref{sec:problemy} předkládá aktuální problémy prezentační vrstvy.
  Část~\ref{sec:pozadavky} definuje požadavky, jež by prezentační vrstva měla
  splňovat.  Další části se podrobněji věnují navrhovaným změnám.  Kapitolu
  opět zakončuje diskuze dopadů na systém (\ref{sec:prezentacnidopady}) a
  shrnutí (\ref{sec:prezentacnishrnuti}).}


\subsection{Problémy prezentační vrstvy}
\label{sec:problemy}

V~oddíle~\ref{sec:prezentacni2} je rozebrána \ientryb{prezentační
  vrstva}{prezentační vrstva} a je jí vytýkáno:

\begin{itemize}
  
\item \emph{Celkový návrh struktury tříd.}
  
  V~diskuzi k~obrázku~\ref{fig:preslayer} je upozorňováno na nevhodné sloučení
  odpovědností\footnote{(1)~\emph{co} se zobrazuje a (2)~\emph{jak} se to
    zobrazuje.} u třídy \cl{Layout\_Base} a je naznačeno možné řešení pomocí
  design patternu \ientrya{model\---view\---controller}, viz
  například~\cite{mvcwiki}.
  
  Design pattern \emph{model--view--controller} slouží k~oddělení datových
  struktur aplikace (model), uživatelského rozhraní (view) a řídícího prvku
  (controller) do třech relativně samostatných částí.  Cílem je zajistit, aby
  změny uživatelského rozhraní měly minimální dopad do datových struktur.
  
  Tento přístup lze ale zobecnit i na jiné oblasti, než pouze uživatelské
  rozhraní --- ve skutečnosti jde o velmi flexibilní způsob, jak snížit
  závislost různých částí kódu, jak uvádí~\cite{javaprof} a jak je vidět
  například z~\cite{framework2}.
  
\item \emph{Nedostatečná podpora nových výstupních formátů, zejména pak XML.}
  
  V~aktuálních verzích \tts{}u je výstup do XML vyřešen doplněním \emph{XML
    metod} (viz~\ref{sec:tutosbase}) do bázové třídy perzistentních objektů
  \cl{Tutos\_Base} a jejich přetížením v~odvozených třídách.
  
  Pro generování XML neexistují žádná doporučení či normy (\leftnote{DTD}{DTD =
    Document Type Definition} apod.), což jednak (1)~činí implementaci metod
  složitou a jednak (2)~je prakticky znemožněno zpracování XML dokumentu podle
  běžných zvyklostí\footnote{Tj.~zpracování pomocí SAX a DOM rozhraní.}.
  
  V~části~\ref{sec:rozdeleni} bylo též poukázáno na diskutabilní začlenění XML
  metod do bázové třídy \cl{Tutos\_Base} s~ohledem na možné využití exportu i
  pro jiné objekty (neodvozené z~\cl{Tutos\_Base}).

\end{itemize}

V~některých částech \tts{}u se objevuje též export do jiných formátů, než XML.
Jedná se například o proprietární formát programu Microsoft~Excel, PDF či
textový CSV.  Většina těchto částí je již na první pohled implementována
nekoncepčně a na jedno použití. To znamená:

\begin{itemize}

\item Často je přistupováno přímo k~databázi, jejíž struktura se může měnit.
  
\item V řadě případů je generován zbytečný kód, který klientem není (a~ani být
  nemůže) nijak využit (jak je poukazováno v~části~\ref{sec:xml})

\item A to vše v~problematické struktuře tříd (viz~\ref{sec:prezentacni2}).

\end{itemize}


\subsection{Požadavky na prezentační vrstvu}
\label{sec:pozadavky}

\modelrot{Prezentační vrstva --- model jednání}{preslayerusecase}

Na obrázku~\ref{fig:preslayerusecase} je vyobrazen \nientrya{model jednání
  prezentační vrstvy}.  Ačkoli \tts{} v~současné podobě umožňuje všechny
možnosti (typy jednání) na něm zobrazené, žádný z~nich není přímo podporován
systémem (například vhodným aplikačním rámcem) a záleží na vývojáři jaký postup
zvolí pro jeho implementaci, přičemž musí čelit v~různé míře problémům shrnutým
v~části~\ref{sec:problemy} (blíže viz oddíl~\ref{sec:prezentacni2}).

Popis jednotlivých aktorů je shrnut v~následující tabulce:

\begin{center}
  \begin{tabular}{p{0.23\textwidth}|p{0.67\textwidth}}
    \emph{Interactive \mbox{Client}} &
    Interaktivní klient představuje běžnou práci uživatele se systémem.  Je
    očekáván HTML výstup (prezentace nebo formuláře) a vstup je zasílán serveru
    přes požadavky HTTP GET a HTTP POST.\\
    \hline
    \emph{Non-interactive Client} &
    Neinteraktivní klient představuje importy/ex\-porty dat do/ze serveru.  Při
    importu je vstup typicky předán přes HTTP požadavek kódovaný jako
    \inlinecode{multipart/form-data} (atribut \inlinecode{enctype} elementu
    \inlinecode{form}).  Exportní soubor může mít různou podobu, nejčastěji
    XML.\\
    \hline
    \emph{Server} & Aktor server představuje serverovou interakci s~prezentační
    vrstvou.
  \end{tabular}
\end{center}

Smysl a stručný popis základních typů jednání předkládá tato tabulka:

\begin{center}
  \begin{longtable}{p{0.23\textwidth}|p{0.67\textwidth}}
    
    \emph{Show special html page} & V~rámci \tts{}u existují určité stránky,
    jež slouží (především) k~administrativním účelům a mají příliš specifické
    chování.  Tyto stránky jsou dostupné pouze v~interaktivním režimu
    (zobrazení v~HTML).  Většinou je nutné mít zcela pod kontrolou jejich
    výstup a jsou typické svým přímým přístupem k~databázi.  (Generování
    některých prvků stránky lze
    zobecnit --- typ jednání \emph{Generate interactive parts}.) \\

    \hline
    
    \emph{Show data page} & Jedná se o stránky, které uvidí uživatel
    nejčastěji.  Zobrazují jednak (1)~aplikační objekty systému\footnote{Tedy
      objekty, jež jsou většinou odvozeny ze třídy \cl{Tutos\_Base}.} (v~různé
    podobě --- graf, formulář) a jednak (2)~seznam aplikačních
    objektů, typicky vše ve formátu HTML.\\

    \hline
    
    \emph{Export data from server} & I u těchto stránek se jedná o zobrazení
    (1)~aplikačních objektů či (2)~jejich seznamu, avšak bez
    interaktivních prvků a v~jiném formátu, typicky XML.\\

    \hline
    
    \emph{Import data to server} & Hromadný import dat na server je
    představován uploadem nějakého souboru a jeho zpracováním.  Ten může být
    realizován prostřednictvím přímého uploadu (HTTP PUT či jiný způsob) nebo
    prostřednictvím formuláře (HTTP POST).  Tento typ jednání představuje oba
    způsoby --- zpracování na serveru se pro ně liší
    minimálně\footnote{Tj.~pouze ve způsobu, jakým se data na server
      dostanou.}.\\

    \hline
    
    \emph{Process input} & Tento typ jednání představuje interakci
    serverové části s~prezentační vrstvou.  Úkolem je (1)~zpracovat data a
    (2)~přeposlat klientovi stránku, jež si vyžádal.\\

  \end{longtable}
\end{center}

Z~modelu jednání je patrné:

\begin{itemize}
  
\item Rozdělení práce klienta na interaktivní a neinteraktivní (dávkové)
  požadavky (aktoři \cl{Interactive Client} a \cl{Non-interactive Client}).
  
\item Hlavní rozdíly a zároveň společné rysy při zpracování interaktivních a
  dávkových požadavků pomocí rozšířených typů jednání.
  
\item Zachování naprosté kontroly nad speciálními případy, jejichž zpracování
  je velmi odlišné od běžných požadavků (typ jednání \emph{Show special html
    page}) --- to je vymezeno pouze pro interaktivní práci.
  
\item Zpracování vstupu na úrovni prezentační vrstvy (typ jednání \emph{Process
    Input}), jak bylo navrženo v~části~\ref{sec:zpracovani} .

\end{itemize}


Primárním požadavkem je co možná největší odstíněnost aplikačních objektů od
jejich prezentace.  Díky tomu bude možné měnit radikálně vzhled interaktivních
stránek i formát výstupu (HTML, XML, \dots), aniž by se to dotklo aplikační
logiky --- je evidentní, že to je právě role design patternu
\ientrya{model\---view\---controller}, viz~\cite{javaprof}, \cite{mvcwiki}.

Dále je třeba zajistit:

\begin{itemize}

\item \emph{Zachovat současný postup při tvorbě stránek.}
  
  \tts{} obsahuje množství napsaného kódu a je nutné do jisté míry respektovat
  současné postupy (diskuze k~tomuto tématu viz~\ref{sec:phpmvc}).  Znamená to:

  \begin{itemize}

  \item Princip tvorby nové stránky se nemění --- nová stránka bude znamenat
    odvození od nějaké společné základové třídy.  Její zobrazení pak volání
    nějaké přetížené metody.
    
  \item Zachování základních služeb poskytovaných \ientryb{služby prezentační
      vrstvy}{prezentační} a \ientryb{služby aplikační vrstvy}{aplikační
      vrstvou}, jak je popisováno v~části~\ref{sec:xml}. (Nyní však budou
    poskytovány odděleně.)

  \end{itemize}

\item \emph{Dobrou podporu referencí na objekty.}
  
  O provázání objektů bylo pojednáváno v~předchozích částech (například
  část~\ref{sec:asociace}).  Prezentační vrstva musí reference mezi objekty
  vhodným způsobem podporovat.  Problémy s~referencemi mohou nastat zejména
  během importu či exportu.  Při importu jsou navíc tyto problémy násobené
  možností aktualizace stávajícího objektu systému\footnote{Podle čeho
    rozpoznat objekty nově vkládané a objekty, jež mají nahradit jiné,
    stávající?}.

\item \emph{Podpora oprávnění.}
  
  Při interaktivní práci je nutné respektovat složitý systém oprávnění, který
  může ponechat část objektu skrytu (typ jednání \emph{Show data page}).
  
  Při neinteraktivní práci (import/export) by se mělo se systémem oprávnění
  zacházet jinak --- import/export se musí provádět s~kompletním objektem,
  nikoli jeho částí (tuto myšlenku lze samozřejmě rozšířit pro potřeby \tts{}u
  na import/export několika propojených objektů, kdy uživatel má právo přístupu
  jen k~některým z~nich\footnote{V~\tts{}u je nejmenší jednotkou nad kterou lze
    nastavit oprávnění právě jeden perzistentní objekt.}).

  \begin{enumerate}

  \item Při \emph{exportu} nejde o tak citlivou oblast --- i kdyby uživatel,
    omezen systémem oprávnění, mohl exportovat objekt a získat tak vizuální
    přístup ke všem jeho částem, stále je nemůže měnit.
    
    V~tomto specifickém případě to lze akceptovat, protože v~drtivé věrtšině
    případů stejně uživatel exportující objekt je jeho vlastníkem.  Jiná
    situace není běžná.
    
  \item Naopak \emph{import} by měl být omezen --- aktualizovat objekt importem
    jiného by nemělo být možné, pokud nad ním importující nemá výhradní
    kontrolu (protože by mohlo dojít k~přepisu částí objektu, jež nemá právo
    číst, natož modifikovat).

  \end{enumerate}

\end{itemize}

Je jistě patrné, že současný návrh a implementace prezentační vrstvy, která
provází \tts{} od jeho počátků a byla původně určena jen pro formátovaný HTML
výstup, již není vyhovující.  Zatímco požadavky na prezentační vrstvu rostly,
její design a implementace zůstával stále stejný.  Proto je namístě uvažovat o
novém návrhu prezentační vrstvy.


\subsection{Analýza nové prezentační vrstvy}
\label{sec:analyza}


\subsubsection{Výchozí situace}
\label{sec:vychozi}

\paragraph{Inspirace}

Než bude podán a diskutován návrh nové prezentační vrstvy, je vhodné se
zamyslet, jaké prvky by mohly pomoci při návrhu a realizaci, vycházeje ze
zkušeností podobných projektů (například~\cite{framework1}, \cite{framework2},
\cite{framework3}, \cite{framework4}):

\begin{itemize}
  
\item \emph{Využití reflexe při komunikaci s~objekty aplikační vrstvy.}  (V~PHP
  je dobrá podpora reflexe obsažena až ve verzi~5, viz~\cite{php5reflection}.)
  
  Zde jsou aktuální možnosti \tts{}u malé --- aktuální stabilní verze se
  vyvíjejí pro PHP verze~4.  Je snahou vývojářů, aby \tts{}~2.0 využíval plně
  vlastností PHP verze 5.
  
\item \emph{Využití informací o aplikaci a propojenosti jejích jednotlivých
    částí,} nejčastěji poskytovaných ve formě XML souborů (kde je snížena
  možnost syntaktické chyby při editaci).  Může jít o informace typu: v~jakých
  souborech jsou uloženy formuláře pro tento objekt, jaký styl použít při
  formátování, \dots
  
  V~této oblasti \tts{} poskytuje pouze služby tříd \cl{Tutos\_Module} a
  \cl{Modules}.
  
\item \emph{Využití různých knihoven pro tvorbu grafických prvků}
  v~interaktivním rozhraní (nabídka, kalendář, ...), tyto prvky často bývají
  označovány jako \emph{widgets} či \emph{controls}.
  
  Zde poskytuje \tts{} několik málo vlastních grafických komponent.
  
\item U aplikací napojených na databázi je podstatná podpora vazeb mezi objekty
  (linků) na aplikační úrovni a řešení perzistence.  Ve spojení s~reflexí lze
  získat velmi mocné nástroje využitelné v~rámci všech vrstev aplikace
  (např.~\cite{hibernate} či~\cite{PyDO}).
  
  V~\tts{}u je perzistence i podpora vazeb řešena uspokojivě.  Reflexe není
  využívána (jak bylo naznačeno, podpora reflexe v~PHP verze~4 není dobrá).

\end{itemize}

\paragraph{Krátké zamyšlení}

Je dobré neztrácet ze zřetele celkový náhled a vidět za abstraktními pojmy
jejich konkrétní naplnění.  Při zobecnění části~\ref{sec:pozadavky} lze
konstatovat, že:

\begin{itemize}
  
\item \tts{} generuje tři formy výstupních informací (stránek):

  \begin{enumerate}
  \item Interaktivní speciální stránky, jež nelze zaškatulkovat.
  \item Interaktivní stránky úzce svázané s~objekty aplikační vrstvy.
  \item Neinteraktivní exportní stránky objektů aplikační vrstvy.
  \end{enumerate}
  
  Je na místě připomenout, že to zcela odpovídá tomu, co bylo probíráno
  v~oddíle~\ref{sec:prezentacni} a je patrno z~obrázku~\ref{fig:layersbrief}.
  
  Potvrzuje se, že (1)~systém je ve svých základech navržen dobře a zároveň to,
  že (2)~předkládaný návrh nenaruší koncept celého systému (vazby mezi
  jednotlivými vrstvami), pokud se bude držet požadavků uvedených
  v~\ref{sec:pozadavky}, ač si může vyžádat řadu změn v~prezentační vrstvě.
  
\item \tts{} zpracovává vstup předaný pomocí protokolu HTTP.  Vstup může být
  vcelku v~libovolné podobě (soubor, několik málo proměnných).
  
  Zpracování vstupu probíhá jakoby \uv{mimo aplikaci}\footnote{Tj.~výkoný kód
    není nijak pevně svázán s~GUI --- propojení je pouze přes atributy
    \inlinecode{action} elemntů \inlinecode{form}, na rozdíl například od jasné
    vazby dané vyvoláním nějaké funkce.}, viz~\ref{sec:aplikacnidopady}, což je
  dáno obecným charakterem webových aplikací\footnote{Některé uváděné zdroje,
    např.~\cite{framework2}, to považují za nedostatek a snaží se zpracovávat
    vstup přes událostní model --- snaží se tak o pevnou vazbu mezi GUI a
    výkonným kódem.}.  V~rámci tohoto zpracování není přímo oddělena
  prezentační a aplikační vrstva (viz~\ref{sec:zpracovani}).
  
  Mezi klientskou a serverovou prezentační vrstvou je zajištěn pouze
  mechanismus obecného předávání zpráv pomocí relace či přímo přes protokol
  HTTP, užívaných nejčastěji k~informování uživatele o výsledku operace.

\end{itemize}

Prezentační vrstva by měla nabízet rozumnou podporu všem těmto činnostem.
Některé jsou lépe strukturované (stránky svázané s~aplikačními objekty) a
v~těchto případech může být podpora při tvorbě stránek ze strany prezentační
vrstvy větší.  U některých může být nabídnut pouze základní rámec zpracování
vstupu/výstupu (speciální stránky a zpracování vstupu).


\subsubsection{Základní koncept}
\label{sec:zakladnikoncept}

Z~rozšířených typů jednání (viz obrázek~\ref{fig:preslayerusecase}) jsou vidět
některé společné prvky, a~dále je z~nich patrné, jaké činnosti musí být
zajištěny.

Za návrhem i implementací stojí snaha o dodržení design patternu
\ientrya{model\---view\---controller}.  Jako model figuruje třída odvozená
z~\cl{Da\-ta\_Mo\-del}.  Role view připadá třídě \cl{Layout} a role controller
je rozdělena mezi ostatní třídy prezentační logiky \cl{Output\_Page},
\cl{Input\_Page}\footnote{Ano i třída \cl{Input\_Page}, protože již zde probíhá
  rozhodování o tom, jaká stránka bude zaslána klientovi.  K~předání tohoto
  rozhodnutí může být užito relace (session) či jiného mechanismu (po té co se
  zpracuje vstup).} a jádro systému \cl{System Core}, viz
obrázek~\ref{fig:preslayerconception}, které spolupracují na tvorbě
výstupu\footnote{Úzké propojení těchto rolí (třeba i v~rámci jedné třídy) není
  tak neobvyklé, viz~\cite{mvcjavaworld}}.

\modelrot{Prezentační vrstva --- zjednodušený model}{preslayerconception}

Následuje krátký popis jednotlivých tříd
z~obrázku~\ref{fig:preslayerconception}:

\begin{itemize}

\item \nientryb{třída \cl{Data\_Model}}{\cl{Data\_Model}}
  
  Tato třída slouží k~prezentaci libovolných dat.  Přetížením abstraktních
  metod by měla být zajištěna:

  \begin{enumerate}
  \item Kontrola dat, metoda \inlinecode{invariant()}.
  \item Zpracování dat odeslaných z~formuláře, metoda\\
    \inlinecode{Data\_Model::parse\_http\_request()}.
  \end{enumerate}
  
  Tato třída odstiňuje aplikační logiku od jakékoli znalosti prezentační
  vrstvy.  Slouží jako prostředník, který přejímá vstup uživatele, kontroluje
  ho a podle potřeby nastavuje datové atributy aplikačních tříd (ať již těch
  odvozených od \cl{Tutos\_Base} či jiných).
  
  Za konkrétní instancí této třídy je možné vidět libovolný HTML formulář a
  s~ním svázaná data\footnote{Nicméně data nemusí být zobrazena ve formuláři
    --- podobu zobrazení řídí až \cl{Output\_Page}.}.

\item \cl{Portable\_Data\_Model} (odvozeno z~\cl{Data\_Model})
  
  Odpovědností této třídy je prezentace dat aplikační logiky.  Ta mohou být
  navíc zobrazována v~neinteraktivním režimu, což značí možnost jejich
  importu/exportu.
  
  Typicky by se mělo jednat o třídy odvozené z~\cl{Tutos\_Base}, avšak není to
  podmínkou.

\item \cl{Output\_Page}
  
  Tato třída je odpovědná za správné zobrazení celkové stránky.  Její instance
  slouží jako kontejner pro objekty, jež mají být předány klientovi.  Samotný
  výstup řídí třída \cl{Layout}.  Přetížením \inlinecode{Outpu\_Page::output()}
  se ovlivní zobrazení objektu třídy \cl{Data\_Model}.
  
  V~případě neinteraktivního výstupu je většinou pouze volána\\
  \cl{Portable\_Data\_Model::export()}

\item \cl{Interactive\_Output\_Page} (odvozeno z~\cl{Output\_Page})
  
  Interaktivní stránka vedle objektů třídy \cl{Data\_Model} zobrazuje i
  interaktivní části stránky (objekty typu \cl{Interactive\_Part}).  Celkové
  rozložení grafických prvků řídí třída \cl{Layout}.
  
  V~rámci této třídy jde o podobný model, jenž byl navržen na
  obrázku~\ref{fig:preslayernew}, tj.~implementace design patternu
  model--view--controller\footnote{Modelem je \cl{Data\_Model}, role view
    připadá na třídu \cl{Layout} (rozhoduje o konkrétním rozvržení na stránce)
    a controllerem je \cl{Interactive\_Output\_Page}, která po svém zobrazení
    poskytuje (a~řídí) způsob, jakým uživatel může provádět změny modelu,
    viz~\cite{mvcjavaworld}.}.

\item \cl{Input\_Page}
  
  Tato třída se stará o zpracování vstupu (\inlinecode{process\_input()}).
  
  V~případě, že je možné očekávat na vstupu objekt třídy \cl{Data\_Model}, má
  situaci značně ulehčenu, protože tyto objekty umí zpracovat vstup samostatně
  (\inlinecode{parse\_http\_request()}, \inlinecode{import()}), v~ostatních
  případech si musí pomoci sama.

\end{itemize}


\subsection{Podrobný model}
\label{sec:model}

Při pohledu na \nientryb{objektový model prezentační vrstvy}{podrobný model}
(obrázek~\ref{fig:preslayerom}) přibylo několik tříd a metod, ale základní
koncept se nemění.

\modelrot{Prezentační vrstva --- objektový model}{preslayerom}

\subsubsection{Celkový přehled}
\label{sec:celkovy}

Tento návrh (obrázek~\ref{fig:preslayerom}) poskytuje lepší podporu pro tvorbu
výstupních stránek než současná využívaná verze, zároveň však ponechává
současné principy nezměněny.

V~části~\ref{sec:navrhshrnuti} a \ref{sec:problemy} je podáno shrnutí
nejpalčivějších problémů prezentační vrstvy, jež jsou
v~oddíle~\ref{sec:prezentacni2} (zejména pak v~\ref{sec:xml}) probrány
podrobněji.  Stručně řečeno (převzato z~\ref{sec:problemy}), prezentační vrstva
trpí:

\begin{itemize}
\item \emph{Celkovým návrhem struktury tříd.}
\item \emph{Nedostatečnou podporou nových výstupních formátů, zejména pak XML.}
\end{itemize}

Jakým způsobem to řeší předkládaný model?

\begin{itemize}

\item \emph{Celkový návrh struktury tříd.}
  
  Stručný popis tříd viz též~\ref{sec:zakladnikoncept}.

  \begin{enumerate}
    
  \item Zavedením \ientryb{třída \cl{Data\_Model}}{třídy \cl{Data\_Model}} bylo
    dosaženo striktního oddělení prezentační vrstvy od aplikační vrstvy v~těch
    místech, kdy ji prezentační vrstva využívá\footnote{Zároveň však
      prezentační vrstva neztrácí přístup ke službám aplikační vrstvy jak jsou
      definovány v~\ref{sec:xml} díky vazbám na jádro aplikace (v~modelu pouze
      symbolicky jako \inlinecode{Output\_Page::System Core}).}.
    
    Bylo též dosaženo jednotné kontroly vstupních dat tak, jak bylo navrhováno
    v~\ref{sec:zpracovani} (\inlinecode{Data\_Model::invariant()} a\\
    \inlinecode{Data\_Model::parse\_http\_request()}).
    
  \item Služby aplikační vrstvy (jádra systému) a služby vrstvy prezentační od
    sebe byly odděleny (část~\ref{sec:xml}).

    Služby prezentační vrstvy jsou navíc nyní rozděleny na služby pro
    interaktivní zobrazení (\cl{Interactive\_Output\_Page}) a služby pro
    neinteraktivní zobrazení (bázová \cl{Output\_Page} a třída \cl{Export}).
    
  \item Byla odstraněna nevhodná dědičnost a nahrazena agregací jak je
    navrhováno v~části \ref{sec:prezentacni2}.  Kód je tak čistší a je možné
    měnit zobrazení kdykoliv, jak je běžné u jiných grafických komponentních
    knihoven.

  \end{enumerate}


\item \emph{Nedostatečná podpora nových výstupních formátů, zejména pak XML.}
  
  Exportovat a importovat je možné (z~logiky věci) jen nějaké perzistentní
  objekty.  Typicky půjde o potomky \cl{Tutos\_Base}, ale teoreticky je možné
  exportovat třeba i nastavení modulu (perzistentní úložiště je soubor
  s~nastavením), pokud bude vůle něco takového implementovat.
  
  Jedná se o rozsáhlejší téma, a~proto je mu věnována samostatná část níže
  (\ref{sec:exim}).

\end{itemize}


\subsubsection[Export/Import]{Export/import a podpora ze strany prezentační
  vrstvy}
\label{sec:exim}

Export potomka třídy \cl{Portable\_Data\_Model} zajišťuje třída \cl{Export},
jež vhodným způsobem přetěžuje metody báze \cl{Output\_Page}.

Primárně je export vždy proveden do XML prostřednictvím\\
\inlinecode{Portable\_Data\_Model::export()} a přilinkováním příslušného XSLT
stylu bude provedena konverze do jiného formátu\footnote{Teoreticky i například
  do HTML a tak tento způsob může být použit i pro zobrazení interaktivních
  dat.  Na první pohled elegantní přístup však skrývá řadu úskalí a v~obecnější
  míře by šel aplikovat jen na objekty s~pevným rozhraním (např.~potomky
  \cl{Tutos\_Base}) a nejlépe ještě s~využitím reflexe.}.

Pro usnadnění komunikace mezi klientem a serverem při exportu je vždy při
každém interaktivním zobrazení aktuální objekt \cl{Portable\_Data\_Model}
uložen na serveru (v~metodě \inlinecode{Output\_Page::process\_output()}) a tak
může být bez problémů použit třídou \cl{Export} k~exportu.

Podobně, jako je snahou exportu rozložit objekt \cl{Portable\_Data\_Model} do
XML, je cílem importu naopak převzít XML a vytvořit z~něho nový objekt\\
\cl{Portable\_Data\_Model}.  Jistě se při tom může uplatnit \ientrya{factory
  method} design pattern.  Importovaný objekt již zná své vazby na aplikační
vrstvu a může provést uložení do příslušných perzistentních úložišť (metoda\\
\inlinecode{Portable\_Data\_Model::persistent\_save()}).

Import je přímo podporován pouze z~XML formátu (třída \cl{Import}), avšak vždy
je možnost přetížit metody třídy \cl{Import} a zajistit tak import z~jiného
formátu (kupříkladu CSV).

Pro bezproblémové zpracování XML je žádoucí definovat jeho strukturu
prostřednictvím \nientrya{DTD} (které může být vloženo přímo do XML souboru a
tak lze příjemci usnadnit maximální možnou měrou jeho zpracování).

Dobře vytvořené DTD může být použito i jinak:

\begin{enumerate}
  
\item Při tvorbě databáze v~době instalace systému jako předpis pro tabulky a
  typy jejich sloupců (u popisu typů se lze inspirovat například specifikací
  XML--RPC~\cite{xmlrpc}).  Mohla by tak být zcela odstraněna nepotřebná třída
  \cl{Query}, viz~\ref{sec:databazova2}.

\item Může částečně nahradit reflexi pro datové atributy objektu.

\end{enumerate}

Pro řešení problémů, jež jsou naznačeny v~části~\ref{sec:pozadavky} --- totiž
(1)~podpora oprávnění ACL a (2)~podpora referencí --- jsou přijata tato
doporučení:

\begin{enumerate}

\item \emph{Podpora oprávnění.}
  
  Při exportu bude oprávnění ignorováno a vždy bude exportován kompletní objekt
  (včetně referencí).  Nebude--li tento model vyhovovat, vždy lze pozměnit
  implementaci tak, aby export nebyl umožněn uživateli, jež nemá kompletní
  kontrolu nad exportovanými objekty\footnote{Může to být vzato v~úvahu při
    generování nabídky například --- pokud oprávnění nemá, nabídka pro export
    se nevygeneruje.}.
  
  Při importu bude vždy vytvářen nový objekt (objekty) pod kontrolou uživatele,
  jenž provádí import.  Aktualizace objektů nebude pro složitost implementace
  podporována.

\item \emph{Podpora referencí.}
  
  DTD lze vytvořit tak, aby se jednotlivé exportované objekty mohly v~rámci
  datového souboru XML vzájemně odkazovat (typ XML atributu \inlinecode{ID} a
  \inlinecode{IDREF}).

\end{enumerate}

O vhodnou podporu těchto doporučení se musí postarat vývojář sám implementací
v~metodách \inlinecode{import()} a \inlinecode{export()}.


\subsubsection{Zamýšlené použití}
\label{sec:zamyslene}

Základní rys předchozího postupu (jedna HTML stránka = jedna nově odvozená
třída) zůstává zachován.  Avšak díky lepší separaci odpovědnosti je možné
uvážlivěji postupovat při exportu/importu a třídu \cl{Data\_Model} lze použít
jako obecný prvek kontroly vstupu.

\paragraph{Tvorba interaktivní stránky}

\begin{enumerate}
  
\item K vytvořené třídě aplikační logiky je nutno vytvořit třídu odvozenou
  z~\cl{Portable\_Data\_Model} (pokud je žádoucí třídu
  exportovat/im\-porto\-vat), nebo přímo z~\cl{Data\_Model}.
  
  Toto je rozdíl oproti předchozímu postupu.  Dříve nebyla hranice mezi
  prezentační vrstvou a aplikační takto vymezena.
  
  Výhodou je jednotné zpracování vstupních dat a již zmiňované oddělení vrstev
  zvyšující nezávislost aplikační vrstvy.

\item Pro každé zamýšlené zobrazení dat příslušného objektu odvozeného od třídy
  \cl{Data\_Model}\footnote{Například (1)~zobrazení a (2)~editace}, je nutné
  odvodit třídu od\\
  \cl{Interactive\_Output\_Page} a přetížit její metody.
  
  Tento krok odpovídá původnímu postupu, kde se odvozovalo od původní třídy
  \cl{Layout}.
  
  Výhodou oproti předchozímu kroku je snadnější přístup k~jádru aplikace
  v~rámci jmenného prostoru třídy (\inlinecode{Output\_Page::System Core}) a
  tím i důslednějšímu oddělení služeb jádra a služeb prezentační vrstvy a lepší
  generování stránky zprostředkované novou třídou \cl{Layout}.

\end{enumerate}

Tvorba speciální HTML stránky (typ jednání \emph{Show special html page}) se
v~ničem neliší.  Pouze první uvedený krok je alternativní.  Pokud se to nehodí,
může se zcela vynechat.  Přístup k~aplikačním a prezentačním službám je
nezměněn.

\paragraph{Tvorba neinteraktivní stránky}

U exportu by mělo pouze dojít k~přetížení metody
\inlinecode{Portable\_Data\_Model::export()} a vygenerování validního XML.
Zbytek odpovědnosti za výstup byl přesunut zcela mimo aplikaci --- do
doprovodných XSLT stylů.

Při XML importu stačí přetížit \inlinecode{Portable\_Data\_Model::import()}.

Při importu z~jiného formátu může být požadováno vedle přetížení metod třídy
\cl{Portable\_Data\_Model} i implementace stránky zpracující vstup (nejspíše
odvozenou od obecnější \cl{Input\_Page}).

Lze si jistě představit i situaci, kdy vývojář bude postupně dodávat podporu
pro XML import/export.  Třídy \cl{Export} a \cl{Import} lze upravit tak, aby
testovaly, zda je možné skutečně třídu importovat/exportovat, a~aby byly
schopné transparentně informovat uživatele v~případech, kdy to nebude možné.

\paragraph{Tvorba stránky zpracovávající vstup}

Při vstupu lze výhodně použít metody třídy \cl{Data\_Model} pro zpracování
vstupu.  Jako objekt \cl{Data\_Model} může vystupovat díky obecnému navržení
libovolný formulář a k~němu navázaná data, která nemusí mít přímou reprezentaci
v~aplikační vrstvě (což lze využít zejména pro implementaci typu jednéní
\emph{Show special html page}).

Z~modelu je sice patrné, že by měla být instance stránky \cl{Input\_Page}, ale
protože v~běžných činnostech půjde nejčastěji o zpracovávání objektů odvozených
od \cl{Data\_Model}, byla by její implementace pouhým dodržováním postupu.

Proto nejspíše není nutné ji vždy implementovat a uchýlení k~běžnému
\uv{skriptování} lze tolerovat.


\subsection{Dopady na systém}
\label{sec:prezentacnidopady}

Zatímco v~předchozích kapitolách, byly navrhované změny spíše minimalistické,
v~této kapitole byla navržena kompletní změna celé prezentační vrstvy.
Naštěstí jde o nejvyšší vrstvu, takže se tyto změny dotknou pouze využívání
vrstev nižších.

\begin{itemize}

\item \emph{Dopady na databázovou vrstvu.}

  Žádné.

\item \emph{Dopady na aplikační vrstvu.}
  
  Třídy aplikační vrstvy od tohoto okamžiku nejsou odpovědné za žádnou
  prezentaci svých dat.  To kompletně přebírají odvozeniny \cl{Data\_Mo\-del} a
  \cl{Output\_Page}.  V~důsledku to znamená odstranění \emph{XML metod} (viz
  část~\ref{sec:tutosbase}).
  
  Dále aplikační třídy ztrácí nutnost kontrolovat vstupní data (to se týká jen
  některých tříd, kde tato kontrola není doposud prováděna v~prezentační
  vrstvě).
  
  \emph{XML metody} bude možné prostě přesunout a změnit do nově vytvořených
  tříd odvozených z~\cl{Data\_Model}.  Tato úprava kódu v~první fázi (přesun)
  bude snadná.  Druhá fáze (úprava) bude vyžadovat vytvořit dobré a (bohužel)
  složité \ientrya{DTD}, až potom bude možné třídy upravit.
  
  Kontrola vstupních dat může být převzata (jistě s~malými úpravami) do metod
  nově vzniklých tříd \cl{Data\_Model}.  Sem by zároveň měla být přesunuta i
  kontrola dat, jež probíhá nyní v~současných třídách/sou\-bo\-rech prezentační
  logiky.

\item \emph{Dopady na prezentační vrstvu.}
  
  Značné.  Kompletní re--implementace.
  
  Jedná se o kompletní změnu struktury tříd, o přesuny odpovědností a o
  zavedení přísnějšího rámce pro tvorbu nových stránek.  Z~vnějšího pohledu se
  sice vše jeví jako dříve, ale vnitřní struktura prezentační vrstvy je jiná.
  
  Prezentační třídy \tts{}u v~současné době tvoří hrubým odhadem asi tak
  $\frac{2}{5}$ kódu (každá zobrazitelná HTML stránka + stránky zpracovávající
  vstup).

\end{itemize}

Rámec pro prezentační vrstvu navrhovaný v~této kapitole je obecný a při jeho
implementaci by bylo vhodné využít i jiné knihovny --- jde zejména o knihovny,
které podporují generování různých ML (Markup Language) --- například
\cl{Smarty}~\cite{smarty}, které by značně zjednodušily jak generování, tak i
výslednou práci s~ML\footnote{Například podporou šablon, parsrovacích
  mechanismů aj.}.

Lze jen doporučit implementovat tyto změny až v~PHP verze 5, tj.~v~\tts{}u~2.0,
jež poskytuje mnohem lepší podporu objektového programování (reflexe, výjimky).


\subsection{Shrnutí}
\label{sec:prezentacnishrnuti}

Tato kapitola podává zcela nový návrh prezentační vrstvy při respektování řady
požadavků a podmínek (\ref{sec:pozadavky}).

Nutnost nového návrhu vychází ze současné neuspokojivé situace
(viz~\ref{sec:problemy}).

Předkládaný návrh odstraňuje vytýkané nedostatky (část~\ref{sec:celkovy}), ale
při jeho implementaci se naráží zejména na (1)~relativně větší vnitřní
složitost a (2)~obsáhlost změn, které přináší.

