Home > J2EE Pattern, java > Bad Practices: Presentation, Business e Integration Tiers

Bad Practices: Presentation, Business e Integration Tiers

18 ottobre 2013

Bad Practices

Nel libro “Core J2EE™ Patterns: Best Practices and Design Strategies, Second Edition” di “Deepak Alur, John Crupi, Dan Malks” sono indicate tutte una serie di bad practices che spesso vengono riscontrate su progetti e che determinano una serie di problemi. Ho pensato di ricapitolare queste casistiche in modo tale da tenerne conto sia in sede di scrittura di codice e sia in sede di refactoring. Tali bad practices vengono riscontrate su tutti i livelli: presentation, business ed integration tiers.

Presentation Tier Bad Practices

  1. Codice di controllo in parecchie pagine di visualizzazione
  2. Passaggio della struttura dati dal Presentation tier al Business tier o agli oggetti di dominio
  3. Consentire la sottomissione di una form duplicata
  4. Esporre le risorse riservate ad un accesso diretto del Client
  5. Utilizzare <jsp:setProperty> per svuotare il contenuto delle proprietà dei javabean
  6. Creazione di Controller di grosse dimensioni
  7. Utilizzare gli Helper al posto degli Scriptlets

Business and Integration Tiers Bad Practices:

  1. Mappare il modello ad oggetti oppure il modello relazionale direttamente sul modello dei bean entity
  2. Mappare ogni caso d’uso con bean di sessione
  3. Esporre gli attributi dei bean tramite i metodi get e set
  4. Racchiudere la ricerca dei servizi nel client
  5. Utilizzare bean di tipo entity come oggetti di sola lettura
  6. Utilizzo di entity bean di piccole dimensioni
  7. Memorizzare interi grafi di oggetti in entity bean
  8. Esporre le eccezioni degli ejb a client di tipo non ejb
  9. Utilizzare i metodi di ricerca dei bean entity per ottenere dei grossi set di dati
  10. Il presentation tier aggrega i dati a partire dai componenti del business tier
  11. Utilizzo di ejb per transazioni di lunga scadenza
  12. Ejb senza stato che ricostruiscono lo stato per ogni invocazione

Presentation Tier

Codice di controllo in parecchie pagine di visualizzazione
PROBLEMA: A volte si ha la necessità di effettuare dei controlli e si inserisce del codice nelle pagine JSP al fine di verificare il rispetto di certe condizioni.
CONSEGUENZA: Questo crea dei problemi in termini di manutenibilità in quanto nel caso in cui si debba cambiare la logica di controllo occorrerà modificare il codice in tutte le JSP.
SOLUZIONE: Per evitare questo problema è possibile introdurre un Controller, eventualmente associato ad un Command, che centralizzi la logica di controllo e le azioni da intraprendere.

controller

Controller

Passaggio della struttura dati dal Presentation tier al Business tier o agli oggetti di dominio
PROBLEMA: il presentation tier passa al business tier o agli oggetti di dominio i dati direttamente tramite l’oggetto HttpServletRequest
CONSEGUENZA: Si viene a creare un forte accoppiamento tra il presentation tier ed il business tier o agli oggetti di dominio, quest’ultimo dovrà conoscere le logiche di estrazione dei dati da HttpServletRequest.
SOLUZIONE: Per evitare questo problema il presentation tier dovrà creare un java bean in cui inserire i dati per poi passarli al business tier o agli oggetti di dominio.

business

Presentation to Business

domain

Presentation to Domain

Consentire la sottomissione di una form duplicata
PROBLEMA: l’utente per errore sottomette la stessa form per 2 volte, per esempio premendo il tasto indietro (BACK) e poi riconfermando la form oppure aggiornando la pagina dell’esito (F5)
CONSEGUENZA: la stessa richiesta viene inviata 2 volte e risulta duplicata, pertanto nel caso in cui l’utente stava effettuando un acquisto si ritroverà con l’acquisto duplicato.
SOLUZIONE: Occorre controllare il flusso del programma per verificare la sua univocità. Un approccio corretto è di utilizzare un token sincronizzato tra client e server. In questo caso all’inizio della transazione viene creato un token, viene salvato nella sessione server ed inserito nelle richieste del client. Se il client invierà un token diverso da quello presente in sessione, ciò vorrà dire che la richiesta inviata è stata duplicata pertanto verrà scartata.

Token Sincronizzato

Token Sincronizzato

Esporre le risorse riservate ad un accesso diretto del Client
PROBLEMA: l’utente può accedere direttamente a delle risorse dell’applicazione, per esempio pagine jsp, file di properties ecc
CONSEGUENZA: Questo comportamento può creare problemi di sicurezza in quanto un utente smaliziato potrebbe capire la configurazione e cercare di modificarla
SOLUZIONE: Occorre nascondere il reale percorso utilizzando un Controller oppure tramite la configurazione del Container. Utilizzando il Controller come intermediaro sarà possibile smistare la chiamata al percorso corretto, oppure utilizzando il container sarà possibile salvare le risorse sotto la cartella WEB-INF ed in questo modo impedire l’accesso a tali risorse.

Restrizione su Container

Restrizione su Container

Restrizione su Controller

Restrizione su Controller

Utilizzare <jsp:setProperty> per svuotare il contenuto delle proprietà dei javabean
PROBLEMA: Si assume che settare una proprietà utilizzando <jsp:setProperty> con valore vuoto determini l’assegnazione a stringa vuota oppure a valore null.
CONSEGUENZA: la specifica prevede che nel caso che non venga passato il parametro il valore precedente viene conservato e non viene resettato pertanto questo genera una incosistenza dei dati.
SOLUZIONE: occorre ricreare un nuovo bean oppure fare il reset dei suoi valori prima di riutilizzarlo.

Creazione di Controller di grosse dimensioni
PROBLEMA: Viene creato un controller in cui sono inserite tutte le logiche di gestione delle chiamata
CONSEGUENZA: il Controller diventa di grosse dimensione e piano piano risulta ingestibile, incomprensibile e non facilmente testabile.
SOLUZIONE: il Controller deve avvalersi di altre classi, Helper e Command, che gestiscano i paramentri della richiesta, ricavino l’azione da intraprendere ed invochino il comando da eseguire per gestire la chiamata, tutto ciò snellisce profondamente il controller e delega le responsabilità.

Controller + Command + Helper

Controller + Command + Helper

Utilizzare gli Helper al posto degli Scriptlets
PROBLEMA: Al fine di ridurre la presenza di scriptlet all’interno di pagine jsp, il codice viene inserito all’interno di classi helper che vengono richiamate tramite tag custom.
CONSEGUENZA: è corretto sostituire gli helper al posto degli scriptlet ma non bisogna incorrere nell’errore di creare dei custom tag di basso livello mentre invece dobrebbero esprimere una astrazione di alto livello di facile comprensione.
SOLUZIONE: occorre creare dei custom tag che consentano, a chi legge il codice della jsp, di comprendere il loro comportamento e tale da spingere al loro riuso.

Helper

Helper

Business and Integration Tiers

Mappare il modello ad oggetti oppure il modello relazionale direttamente sui bean Entity
PROBLEMA: Tutti gli oggetti di dominio oppure tutte le tabelle del database vengono rappresentate da bean Entity
CONSEGUENZA: Il numero dei bean Entity aumenta notevolmente e genera dei problemi di prestazione a causa dell’occupazione di molta memoria e di risorse
SOLUZIONE: E’ preferibile realizzare dei bean Entity compositi che relazionino con altre classi al fine di creare un gruppo ridotto oppure realizzare dei Facade che nascondino la complessità.

Inter-Entity Bean Communication

Inter-Entity Bean Communication

Merge Session Beans

Merge Session Beans

Mappare ogni caso d’uso con Session Bean
PROBLEMA: Per ogni caso d’uso viene realizzato un Session Bean in modo tale da servire nello specifico ogni tipo di interazione
CONSEGUENZA: si vengono a creare un numero molto eleavato di Session Bean con conseguenze sulle prestazioni e sulla complessità dell’applicazione
SOLUZIONE: occorre nascondere la complessità attraverso delle classi Facade ed inoltre occorre aggregare i Session Bean in modo da ridurne il numero

Esporre gli attributi dei Bean tramite i metodi get e set
PROBLEMA: per rendere disponibile gli attributi al client, vengono esposti tutti gli attributi tramite i metodi get e set dei Bean
CONSEGUENZA: questo comporta un eccessivo traffico di rete ed una gestione dei dati troppo dettagliata.
SOLUZIONE: usando il pattern Transfer Object viene creato un oggetto che detiene tutte le informazioni e viene restituito al client. In questo modo riduciamo il traffico di rete e la quantità di invocazioni.

Transfer Object

Transfer Object

Racchiudere la ricerca dei servizi nel client
PROBLEMA: Racchiudere nel client o nel presentation tier le logiche di invocazioni degli EJB tramite JNDI
CONSEGUENZA: In caso di modifica delle invocazioni occorre ritoccare il codice in tutte i client
SOLUZIONE: Utilizzare il pattern Business Delegate per spostare la logica dal presentation al business tier ed utilizzare il pattern Service Locator per incapsulare la logica di invocazione degli EJB tramite JNDI

Introduce Business Delegate

Introduce Business Delegate

Service Locator Sequence Diagram

Service Locator Sequence Diagram

Utilizzare bean di tipo entity come oggetti di sola lettura
PROBLEMA: Utilizzo bean di tipo entity in modalità sola lettura
CONSEGUENZA: il container invocherà per tutti i Bean il metodo ejbStore() che serve per sincronizzare il bean con il database e ciò degrada inutilmente le prestazioni
SOLUZIONE: usare il pattern Session Facade che utilizza il pattern DAO.

Data Access Object Sequence Diagram

Data Access Object Sequence Diagram

Utilizzo di Bean Entity di piccole dimensioni
PROBLEMA: Utilizzare gli Bean Entity ed apportare piccole ma frequenti modifiche al loro contenuto.
CONSEGUENZA: Questo comporta la generazione di un forte traffico di rete ed un grosso lavoro per il container il che degrada le prestazioni
SOLUZIONE: Creare dei Bean di grosse dimensioni ed apportare su di esso grosse ma poche modifiche in modo da non degradare le prestazioni.

Memorizzare interi grafi di oggetti in entity bean
PROBLEMA: Nei Bean Entity vengono memorizzati degli alberi di oggetti
CONSEGUENZA: In sede di caricamento, di salvataggio o di sincronizzazione dei Bean Entity con il database, le performance sono degradate in quanto occorre eseguire le operazioni su di un numero molto elevato di oggetti che dovranno essere sincronizzati con il database
SOLUZIONE: Caricare solo la parte del grafo di interesse oppure marcare la parte del grafo che deve essere sincronizzata con il database utilizzando il pattern Store Optimization Strategy.

Store Optimization Strategy Sequence Diagram

Store Optimization Strategy Sequence Diagram

Esporre le eccezioni degli EJB a client di tipo non EJB
PROBLEMA: far ritornare l’errore di un EJB direttamente ad un client che non è di tipo EJB
CONSEGUENZA: Il client potrebbe non sapere come comportarsi in base all’eccezione ricevuta in quanto il funzionamento del server non è noto
SOLUZIONE: Occorre disaccoppiare il client dall’ejb utilizzando il pattern Business Delegate che introduce un intermediario tra i due attori che si occupa di gestire le comunicazione e di nascondere la complessità e gli errori del server.

Introduce Business Delegate

Introduce Business Delegate

Utilizzare i metodi di ricerca degli Entity Bean per ottenere dei grossi volumi di dati
PROBLEMA: Per effettuare delle ricerche sui dati vengono utilizzati i metodi di ricerca degli EJB che ritornano una referenza all’oggetto remoto che detiene i dati
CONSEGUENZA: L’invocazione di EJB comporta un aumento del traffico di rete che degrada le prestazioni
SOLUZIONE: Occorre utilizzare il pattern DAO per accedere ai dati ed effettuare delle ricerche per poi  utilizzare il pattern Transfer Object per trasferire l’oggetto al client il quale può cercare in questo senza generare richieste remote.

Il Presentation Tier aggrega i dati ottenuti dal Business Tier
PROBLEMA: il client ha bisogno di aggregare i dati ricevuti dal Business Tier
CONSEGUENZA: questa attività di aggregazione ad opera del client comporta un uso eccessivo della rete per recuperare i dati ed inoltre richiede che il client abbia conoscenza delle logiche di aggregazione dei dati
SOLUZIONE: eseguire la fase di aggregazione direttamente nel business tier e restituire il dato già aggregato. In questo caso si può utilizzare il pattern Transfer Object Assembler.

Transfer Object Assembler Sequence Diagram

Transfer Object Assembler Sequence Diagram

Utilizzo di EJB per transazioni di lunga scadenza
PROBLEMA: Utilizzo di EJB per eseguire delle operazioni che richiedono molto tempo per la loro esecuzione o che prevedono un tempo di pausa durante la loro attività.
CONSEGUENZA: tutte le risorse utilizzate dagli EJB non sono disponibili per altre attività fino al loro completamento e questo comporta un problema potenziale in termini di prestazioni
SOLUZIONE: Occorre prevedere la presenza di un MOM Message Oriented Middleware e di utilizzare JMS Java Messagging Services per rendere asincrono il processo. In questo caso si può utilizzare il pattern Service Activator.

Service Activator Sequence Diagram

Service Activator Sequence Diagram

Ejb senza stato che ricostruiscono lo stato ad ogni invocazione
PROBLEMA: Per motivi di performance si decide di utilizzare Session Bean di tipo Stateless ma durante lo sviluppo ci si accorge che si necessita di uno stato per gestire la sessione pertanto si inseriscono delle informazioni sullo stato
CONSEGUENZA: Questi EJB Stateless vengono utilizzati in modo improprio
SOLUZIONE: Occorre capire se occorre mantenere o meno lo stato in EJB State less/full.

Categorie:J2EE Pattern, java
%d blogger cliccano Mi Piace per questo: