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/[email protected]/
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.
([email protected])
|