Internet
Business - PC Magazine Romania, Martie 2001
Dezvoltarea aplicaţiilor web folosind arhitectura Model-View-Controller (MVC)
model 2 şi Apache Struts
Sorin Scorţan
Model-View-Controller (MVC) este un design pattern care leagă eficient interfaţa
cu utilizatorul de modelul de date în programarea orientată pe obiecte. Această
arhitectură este larg utilizată în programarea în limbajele Java, C++ sau Smalltalk,
permiţând reutilizarea codului sursă şi reducând astfel durata de dezvoltare
a aplicaţiilor cu interfeţe utilizator.
Arhitectura model-view-controller se constituie din trei componente principale:
- componenta Model, reprezentată de structura logică de date a aplicaţiei
şi clasele de nivel înalt asociate cu ea. Componenta Model nu conţine informaţii
despre interfaţa utilizator.
- componenta View, care este o colecţie de clase reprezentând interfaţa cu
utilizatorul (toate obiectele pe care utilizatorul le poate vedea pe ecran
şi cu care poate interacţiona, cum ar fi butoane, casete de text, etc.)
- componenta Controller, care reprezintă clasele ce realizează comunicarea
între clasele din Model şi cele din View
Dacă sunteţi în căutarea unei arhitecturi solide şi viabile, care să vă uşureze
implementarea aplicaţiilor web de o manieră modernă şi de viitor, atunci nu
veţi putea face abstracţie de aşa-numita arhitectură Model-View-Controller(MVC)
.
Una din implementările cele mai reuşite ale acestei arhitecturi este framework-ul
STRUTS, dezvoltat de către Apache Group ca open source în cadrul proiectului
Jakarta.
Pentru a înţelege avantajele oferite de Struts şi a putea evalua ce tipuri
de proiecte se pretează cel mai bine în a fi abordate şi soluţionate cu Struts,
să urmarim întâi tipul de MVC care a fost implementat în această colecţie puternică
de clase Java, ca şi avantajele şi dezavantajele acestei alegeri.

MVC Model 1 versus Model 2
Arhitectura MVC s-a dezvoltat în urma nevoilor practicii în două modele uşor
diferite. Modelul 1 poate fi exemplificat printr-o aplicaţie simplă de login,
a cărei structură este prezentată în Figura 1.
Logica procesului este secvenţială şi evoluează din pagină în pagină.
Pagina logon.jsp conţine o formă în care se introduc datele de la utilizator.
Pagina logon_action.jsp utilizează o clasă JavaBeans User pentru verificarea
datelor şi setarea proprietăţilor Bean-ului cu valorile pentru user şi parolă.
Dacă valorile lipsesc sau sunt incorecte, se transferă controlul înapoi paginii
logon.jsp. Dacă datele sunt corecte, se transferă controlul paginii home.jsp,
care afişează un mesaj de bun venit utilizatorului.
Întreaga logică a aplicaţiei se execută la nivelul paginilor JSP, care folosesc
atât cod Java pentru validări cât şi cod HTML pentru afişarea rezultatelor.
Paginile logon.jsp şi home.jsp constituie componenta de View din model, iar
pagina logon_action.jsp constituie componenta de Controller si Model. Clasa
User reprezintă un obiect business.
După cum se observă, în paginile JSP se pot amesteca rutine ce ţin de logica
aplicaţiei (JavaBeans), procesarea la nivel de server (Java si JSP), precum
si scripturi la nivel de client (HTML, JavaScript). Containerul JSP e cel care
va executa aceste rutine şi va transmite rezultatele către una sau alta dintre
componentele JSP.
Modelul 1 poate fi utilizat cu succes la dezvoltarea de situri simple, avantajul
său fiind viteza de dezvoltare a paginilor JSP. Dezavantajele modelului 1 constau
în amestecul de componente logice şi limbaje la nivelul paginilor JSP, ceea
ce face întreţinerea lor mai dificilă şi conduce la imposibilitatea reutilizării
lor pentru alte aplicaţii.
Modelul 2 reprezintă o structura bazată pe arhitectura model-view-controller
(MVC) 2.
Fluxul aplicaţiei este mediat de un Controller central (un servlet sau o colecţie
de servleturi), care are rolul de a delega cererile HTTP către clasa Java care
să le gestioneze.
Componenta Model este constituită dintr-un ansamblu de clase Java care înmagazinează
logica aplicaţiei şi starea sistemului. După ce logica necesară este executată
la nivelul componentelor Model, controlul este transferat înapoi la Controller
care îl transmite către paginile JSP care joacă rol de componentă View. Alegerea
uneia dintre paginile View care să preia controlul este determinată la nivelul
unui fişier de mapări (de regulă un fişier de configurare XML).
În acest fel, modelul MVC realizează separarea în componente distincte a logicii
aplicaţiei de procesarea la nivel de server şi de logica de afişare a rezultatelor.
Această separare permite fiecărei componente să poată fi reutilizată şi asigură
o întreţinere mai uşoară a întregii aplicaţii.
Prezentarea arhitecturii Struts
Arhitectura Struts se bazează pe modelul MVC2 şi a fost elaborată ca proiect
open-source de către Apache Group în cadrul proiectului Jakarta. Ultima versiune
existentă este Struts 1.0 şi poate fi încărcată şi studiată de pe situl <http://jakarta.apache.org/struts>.
Structura arhitecturii Struts este prezentata în Figura 2.

Componentele arhitecturii Struts, prezentate în ordinea în care participă la
proces, sunt:
a. web.xml - fişier de configurare verificat de containerul JSP la pornire.
Se specifică controlerele aplicaţiei (ex. Action servlet, database servlet),
parametrii de iniţializare ai controllerelor (nivelul de debug, dacă se încarcă
la startup), maparea unui pattern pentru cererile URI (ex. *.do) la un anumit
controler, fişierul JSP de start şi locaţia bibliotecilor de taguri JSP Struts
precum si a bibliotecilor de taguri create de utilizator
b. Cererea - cererea HTTP de la utilizator. Se cere afişarea unei anumite
pagini sau se transmite o formă cu date de intrare. Această cerere este interceptată
de controler
c. Controlerul - este procesorul central al arhitecturii şi este responsabil
pentru rutarea cererilor HTTP la obiectele corespunzătoare din arhitectură.
Controlerul este un servlet (ActionServlet). Pot exista mai multe servleturi
la nivel de aplicaţie (ex. DatabaseServlet pentru iniţializarea unui connection
pool şi conectarea la o bază de date). Când controlul este iniţializat, se citeşte
fişierul de configurare struts-con. Figura xml ce specifică acţiunile mapate
la nivelul aplicaţiei. Controlerul utilizează aceste mapări pentru a determina
unde să transfere cererea HTTP. Controlul poate fi transferat unei clase Action
care să execute logica aplicaţiei, sau înaintat unei componente JSP pentru afişarea
în browser.
d. Struts-conFigura xml - fişier de configurare care păstrează toate
acţiunile mapate la nivelul aplicaţiei. Se asigură modularizarea aplicaţiei
şi prevenirea apelului direct al unei componente din browser. Maparea acţiunilor
este păstrată în memorie la nivelul unor clase ActionMapping. O clasă ActionMapping
defineşte o cale URI care corespunde cererii HTTP sosite din browser şi specifică
numele clasei Action care va executa această cerere. De asemenea se specifică
dacă validarea datelor sosite împreună cu cererea se face la nivelul clasei
ActionForm sau al clasei Action. Se mai specifică şi unde se transferă controlul
în cazul în care execuţia logicii se realizează cu succes sau în cazul în care
apare o eroare la validare.
e. Model - modelul este reprezentat de un obiect ce preia răspunsul
de la utilizator şi îl păstrează pe durata procesului. De regulă modelul este
constituit din clase ActionForm şi clase Action. Clasele ActionForm au forma
unor JavaBeans cu metode set() şi get() care înmagazinează pe durata aplicaţiei
datele introduse de utilizator în formele HTML. De obicei există câte o clasă
ActionForm pentru fiecare formă de intrare. Validarea datelor poate fi executată
şi la nivelul claselor ActionForm prin suprascrierea metodei validate(). Clasele
ActionForm mai conţin şi metoda reset() pentru reiniţializarea proprietăţilor
în cazul în care utilizatorul apasă butonul Reset dintr-o formă.
În cazul în care un anumit proces nu necesită utilizarea unui obiect model,
controlerul va transmite controlul direct unui obiect View.
Clasele Action vor executa logica aplicaţiei. Ele pot apela proprietăţile unor
obiecte de business (independente de implementare), pot actualiza sau citi date
din baza de date şi pot executa operaţii de validare. Eventualele erori găsite
pe durata validării sunt scrise sub forma unor obiecte ActionError într-o colecţie
de erori ActionErrors, urmând a fi afişate de componenta View folosind un tag
Struts <html:error>
La final se scriu în contextul containerului toate obiectele necesare pentru
afişarea rezultatelor, iar controlul este transferat către controler care îl
redirecţionează către o componenta View specificată în struts-conFigura xml
a. Obiecte business - obiecte ce înmagazinează datele aplicaţiei. De regulă
sunt obiecte care extind clasa Java. lang.object şi sunt independente de clasele
Struts sau HTTP Servlets, avantajul fiind că pot fi reutilizate şi în alte aplicaţii.
Ele sunt apelate de clasele Action sau din paginile JSP de ieşire.
b. View - obiectele View sunt pagini JSP care afişează în browser rezultatele
cererii. Paginile JSP conţin taguri Struts ca şi taguri definite de utilizator.
Ele nu conţin cod Java ca în modelul 1, astfel încât paginile JSP pot fi implementate
de un web designer fără cunoştinţe de Java. Mesajele afişate în browser pot
fi internaţionalizate cu ajutorul fişierului de resurse
c. Biblioteci de taguri Struts - sunt componente Struts utilizate de obiectele
View pentru afişarea logicii aplicaţiei. Ele mapează toate tagurile HTML precum
şi codul Java existent în paginile JSP de model 1.
d. Fişiere de resurse proprietăţi - sunt fişiere de proprietăţi care păstrează
mesajele afişate în obiectele View, utile în internaţionalizarea aplicaţiei
web.
e. Răspunsul - reprezintă pagina finală pe care utilizatorul doreşte s-o vadă,
de regulă un obiect View ca o pagina JSP.
Avantajele arhitecturii Struts:
- Struts permite modularizarea componentelor aplicaţiei, de aici rezultând
o dezvoltare mai rapidă a componentelor şi specializarea lor pentru realizarea
anumitor funcţii, cu avantaje în reutilizarea componentelor şi în alte aplicaţii.
- Starea variabilelor introduse în formele HTML este păstrată la nivel de
server în bean-uri ActionForm, fiind uşor de procesat şi de păstrat de-a lungul
aplicaţiei. Controlerul verifică existenţa unei instanţe a beanului de clasa
respectivă, iar dacă nu există se creează imediat una şi se adaugă la sesiune.
Apoi controlerul apelează metoda set () a fiecărui parametru din cererea HTTP
ce se potriveşte cu numele unei proprietăţi în bean.
- Există posibilitatea execuţiei logicii aplicaţiei în mai mulţi paşi de către
mai multe clase Action care cooperează între ele şi care păstrează informaţiile
importante la nivelul contextului container al aplicaţiei. Ele pot apela proprietăţi
ale unor obiecte de business care păstrează starea aplicaţiei sau pot apela
obiecte care mapează datele din baza de date.
- Struts are un mecanism propriu de culegere a erorilor în obiecte ActionError
şi de afişare a lor într-o formă internaţionalizată. Operaţiunile de validare
a datelor introduse de utilizator se realizează la nivelul componentelor model
(ActionForm si Action) şi nu la nivelul componentelor View.
- Obiectele business create în modelul 1 pot fi utilizate şi cu arhitectura
Struts.
- Struts poseda un mecanism de log la nivel de context container, cu specificarea
nivelelor de log şi a mesajelor ce se vor înmagazina într-un fişier de log.
- Struts conţine suport pentru baze de date şi are o clasă ce creează un connection
pool, accesat prin JDBC. În fişierul struts-conFigura xml se pot defini mai
multe surse de date.
Dezavantajul principal al arhitecturii Struts este acela că este destul de
complex şi necesită o perioadă de învăţare şi de acomodare atât cu terminologia
specifică modelului MVC 2, cât şi cu funcţionalitatea componentelor şi comunicarea
dintre ele.
Referinţe
1. Arhitectura Struts din proiectul Apache Jakarta -
//jakarta.apache.org/struts
2. Arhiva Struts - //www.mail-archive.com/struts-user@jakarta.apache.org/
3. Husted Dot Com - //www.husted.com/struts/
4. Struts, an Open-Source MVC Implementation (articol despre Struts) - //www-106.ibm.com/
developerworks/ library/j-struts/index.html?open&l=jls
Concluzii
Aspectul cel mai important al arhitecturii Struts este soliditatea designului
său. Arhitectura integrată Struts permite dezvoltarea mai rapidă a aplicaţiilor,
internaţionalizarea lor şi separarea ca şi paralelizarea sarcinilor de programare
între programatorii Java şi web designeri. În plus, dezvoltatorii se pot concentra
pe dezvoltarea logicii aplicaţiei şi pe prezentarea datelor către utilizator,
lăsând comunicarea dintre componente pe seama arhitecturii Struts.
(ss@secure-net.ro)
|