Kosmous beyond the clouds: Sviluppo, Formazione e Consulenza Informatica

Utilizzo del Pattern MVC

Cosa si intende per pattern?

Nell'ingegneria del software un pattern può essere definito "una soluzione progettuale generale ad un problema ricorrente", non è una libreria o un componente di software riusabile, ma una descrizione o un modello da applicare per risolvere un problema che può presentarsi in diverse situazioni durante la progettazione e lo sviluppo del software.

La differenza tra un algoritmo e un pattern è che il primo risolve problemi computazionali, mentre il secondo è legato agli aspetti progettuali del software.


ARCHITETTURA J2EE IN BREVE

I 4 livelli dell'architettura J2EE:
  1. livello per la funzionalità del client(front end che risiedono sul client ) contiene le applicazioni che devono essere presentate all'utente finale.
  2. livello per il supporto web contiene tutte le componenti che estendono il tradizionale server Web,quindi servlet e JSP che sono eseguite sul server,a questo arrivano le richieste fatte dal client via HTTP e questo risponde generando codici HTML che vengono letti dal client.
  3. livello per la logica di business(EJB) contiene le componenti che gestiscono la logica applicativa, queste componenti elaborano dati seguendo le regole business dell'organizzazione.
  4. livello per l'integrazione EIS contiene le componenti per la gestioni dei dati della base di dati di back-end che sono eseguite sul server del data base.
I componenti essenziali di una applicazione J2EE sono le Jsp (Java server pages), le Servlet e gli Ejb (Enterprise java beans).


PATTERN MVC

Per introdurre il concetto del pattern MVC partiamo da un esempio: supponiamo di avere due classi che devono scambiarsi dei valori, ovvero una classe deve prendere un valore da un'altra classe e settarlo al suo interno, un modo per risolvere questo problema e quello di crearsi due classi dove all'interno dell'una viene instanziata e utilizzata l'altra. Di seguito l'esempio di codice:

public class Model {
private int val;
public void setVal(int val){
this.val = val;
}
public int getVal(){
return(val);
}
}

public class View {
//istanzio la classe Model
private Model model = new Model();
private int val;
public void setVal(int val){
this.val = val;
}
public int getVal(){
return(val);
}
public void scambiaVal(){
//Utilizzo la classe Model su istanziata
val = model.getVal();
}
}

Nel nostro caso all'interno della classe View instanziamo la classe Model e prendiamo il valore che ci serve. Tutto quello fin qui scritto è corretto, risolve il problema ma non risponde a pieno alla filosofia della programmazione ad oggetti perché nel momento in cui si dovesse usare la classe View mi dovrei sempre portare dietro la classe Model in quanto le due sono una dipendente dall'altra.

Per superare questo problema possiamo modificare le due classi ed aggiungerne una terza in modo da non avere la dipendenza tra le classi Model e View.

L'esempio viene così modificato:

public class Model {
private int val;
public void setVal(int val){
this.val = val;
}
public int getVal(){
return(val);
}
}

public class View {
private int val;
public void setVal(int val){
this.val = val;
}
public int getVal(){
return(val);
}
}

public class Controller {
private Model model = new Model();
private View view = new View();
public void scambiaVal(){
this.val = val;
view.setVal(model.getVal());
}
}

In questo modo abbiamo tre classi di queste due sono indipendenti e abbiamo scritto una terza classe che contiene la logica applicativa del progetto, che non sarà usata in altri progetti.

Quindi nel caso i cui mi dovesse servire la classe View definita in questo progetto io posso usarla senza dovermi portare dietro la classe Model come succedeva nel caso precedente.

Per chi ha dimestichezza con l'UML quello descritto finora può essere rappresentato con i seguenti schemi:


Primo caso


Secondo caso



Vediamo come quel che è stato detto finora può essere applicato ad una web application:



Considerando lo schema illustrato sopra vediamo come opera una web application:
  • il browser invia una richiesta al server web
  • nel server web una Servlet ha il compito di gestire la richiesta con i dati inviati dal browser
  • la Servlet istanzia un JavaBean e valorizza le proprietà delle classi con i valori recuperati dalla richiesta HTTP
  • la Servlet chiama i metodi del JavaBean in modo da elaborare i dati
  • la Servlet fa un Forward della richiesta alla Jsp che si deve preoccupare di visualizzare i dati a video
In una web Application quello che viene detto Controller, nell'esempio precedente, sono le Servlet quello che è chiamato View sono le JSP e quello che è chiamato Model sono i JavaBean, le Servlet dicono alle View come rappresentare i dati e al Model come gestirli.

L'architettura mostrata sopra, è un'implementazione server-side dello schema Model/View/Controller. Qui la componente presentazione ha il solo scopo di generare la risposta in HTML/XML da inviare al browser. I componenti Front elaborano le richieste HTTP e sono responsabili della creazione dei beans che saranno usati nella presentazione, nonché di scegliere a quale componente della stessa rinviare la richiesta. I componenti Front possono essere sia servlet che pagine JSP.

Il vantaggio di quest'architettura è che non avviene nessuna elaborazione nei componenti della presentazione, il loro unico scopo è di inserire il contenuto dinamico all'interno della parte statica.

Questo tipo di architettura separa chi deve scrivere codice Java da chi deve solo preoccuparsi di scrivere codice HTML.

Il Model solitamente è il livello che si connette ai DataBase, ad EJB etc...

Se in produzione ci dicono di dover cambiare la pagina HTML in ingresso, basta prendere un editor e modificare o l'HTML o la JSP, alla chiamata successiva di quella funzione la JSP in automatico viene ricompilata e l'utente vedrà la nuova versione, i vantaggi sono che non abbiamo fermato il servizio e che non abbiamo dovuto toccare il codice della logica applicativa.




ESEMPIO

Questo semplice esempio di applicazione Web prende dei valori che vengono inseriti dall'utente in una form HTML passandoli alla servlet che esegue la moltiplicazione e li invia su una pagina JSP l'output della quale viene inviato al browser.

L'utente vedrà una pagina HTML con il risultato della moltiplicazione. Codice Servlet

package mvc;
import mvc.JavaBean;

public class Servlet extends javax.servlet.http.HttpServlet{
public void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException,
java.io.IOException{
javax.servlet.ServletContext sc;
javax.servlet.RequestDispatcher rd;
try{
mvc.JavaBean javaBean = null;
// istanzia il JavaBean
javaBean = new mvc.JavaBean();
request.setAttribute("javaBean", javaBean);
// inizializza la proprietà x del bean
javaBean.setX(Integer.parseInt(request.getParameter("x")));
// inizializza la proprietà y del bean
javaBean.setY(Integer.parseInt(request.getParameter("y")));
// Invoca moltiplica sul javaBean.
javaBean.moltiplica();
sc = getServletContext();
rd = sc.getRequestDispatcher("/ServletResults.jsp");
//si forwarda la risposta
rd.forward(request, response);
}
catch(Throwable theException){
// Gestione errore
}
}
}


Codice JavaBean

package mvc;

public class JavaBean{
private int x = 0;
private int y = 0;
private int risultato = 0;

public JavaBean(){
super();
}
public void setRisultato(int newRisultato){
risultato = newRisultato;
}
public int getRisultato(){
return(risultato);
}
public void setX(int newX){
x = newX;
}
public int getX(){
return(x);
}
public void setY(int newY){
y = newY;
}
public int getY(){
return(y);
}
public void moltiplica(){
risultato = x * y;
}
}


Codice Jsp

<HTML>
<HEAD></HEAD>
<BODY>
<jsp:useBean id="javaBean" class="mvc.JavaBean" scope="request"></jsp:useBean>
<TABLE border="0">
<TR>
<TD>risultato</TD>
<TD>
<%=javaBean.getRisultato() %>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
Commenti (0)2006-07-19