Browsing the archives for the Design Patterns category.


Cache Management con il Pattern Singleton

Design Patterns

Così come promesso nel precedente articolo, in seguito alla soluzione proposta dallo stimato Marco Carlini, voglio mantenere la parola e scrivere questo articolo sul cache management.

Per chi non avesse letto il mio precedente articolo sulla Business Delegate, il problema evidenziato era dato dal fatto che veniva adottata l’onerosa Reflection per istanziare a runtime le classi di Business.

La soluzione proposta da Marco è stata quella di adottare un sistema di Chache Management per memorizzare, una volta istanziate, le classi di Business così da risparmiare le risorse almeno nei richiami successivi.

Trovandoci in ambito J2EE e avendo sfruttato il framework web Struts, la prima cosa venuta in mente per mettere, passatemi il termine “la pezza” :) , è stata quella di inserire queste classi nella Session, ma… da sempre ho trovato inserire oggetti in session come mettere in uno sgabuzzino tutti gli oggetti a cui non sappiamo trovare una sistemazione e quando dobbiamo andare a ritrovarli… ahi… che sorprese.

Oltre che poco nobile come soluzione, per trovarne una degna di tale nome, mi sono posto le seguenti domande:

Inserire gli oggetti in session è una soluzione di sicuro semplice, nel momento in cui stiamo inserendo il valore, ma è altrettanto semplice quando (e per chi) la si vuole ritrovare?

Mettiamo il caso che stiamo lavorando con un’applicazione Java, come un’Applet, non avendo sessioni, come possiamo memorizzare i dati e mantenerli persistenti?

La session ovviamente non è la risposta a queste due domande.

“La soluzione migliore è sempre la più semplice”. Io interpreto questa frase nel seguente modo, la soluzione per essere semplice deve esserlo sempre, semplice anche per chi la sfrutta e non solo per chi la realizza.

Senza andare tanto lontano e trovare soluzioni “poco semplici” la GoF come sempre ci viene incontro e ci fornisce una soluzione veramente semplice sia per chi la realizza che per chi la utilizza attraverso il Pattern Singleton.

Così come si può leggere su numerosi libri e su Internet, il pattern Singleton può essere implementato in diversi modi e appassiona molti studiosi . In particolar modo mi ha colpito la soluzione del Prof. Bill Pugh il quale fornisce una soluzione… semplice :) come serve a noi.

public class Singleton {

private static Singleton singleton = null;

private Singleton(){}

public static Singleton getInstance(){

if(singleton == null) singleton = new Singleton();

return singleton;

}

}

 

o ancora meglio (il final ci dà la certezza)

private Singleton() {}

/**
* SingletonHolder è caricato alla prima esecuzione di Singleton.getInstance()
* o al primo accesso al SingletonHolder.instance , not before.
*/
private static class SingletonHolder {
private final static Singletoninstance = new Singleton();
}

public static SingletongetInstance() {
return SingletonHolder.instance;
}

Essendo privato, il costruttore può essere istanziato solo all’interno della classe, infatti come si vede, è il metodo interno getInstance() che controlla che la classe Singleton sia già stata istanziata almeno una volta. Se non è stata istanziata (singleton == null) provvede a farlo, altrimenti semplicemente ritorna la classe che è stata evidentemente istanziata prima. Da notare l’importanza del metodo statico, il quale nel momento in cui viene caricata la classe, in automatico viene memorizzata.

Questo è bellissimo e fa proprio al nostro caso, una classe intelligente che indistintamente dal fatto che noi sappiamo o no se è già stata istanziata se ne occupa lei di creare l’istanza e mantenerla in cache nella Virtual Machine restituendocela quando la richiamiamo. Ora che abbiamo creato la classe di base, al suo interno possiamo metterci tutte le variabili di cui abbiamo bisogno. Nel nostro caso abbiamo bisogno di memorizzare le classi di Business. Anche una semplice HashMap può fare al caso nostro, una mappa in cui inseriremo però solo le classi Business. La chiave sarà data dal nome della classe e il valore sarà la classe stessa.

public class Singleton {

private static Singleton singleton = null;

private HashMap businessClasses = new HashMap();

private Singleton(){}

public static Singleton getInstance(){

if(singleton == null) singleton = new Singleton();

return singleton;

}

public HashMap getBusinessClasses() {

return businessClasses;

}

public void setBusinessClasses(HashMap businessClasses) {

this.businessClasses = businessClasses;

}

}

E’ inutile dire che ovviamente sfrutteremo i getters e i setters per impostare e richiamare le classi nella nostra cache.

Il vecchio codice per istanziare una classe di business era il seguente

public class BusinessExample {

public static BusinessInterface getBusinessInterface(String businessClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{

Class c = Class.forName(businessClassName);

BusinessInterface bus = (BusinessInterface)c.cast(c.newInstance());

businessClasses.put(businessClassName, bus);

return bus;

}

}

Come si vede, ad ogni richiamo, la classe verrà istanziata attraverso la Reflection, che sia stata già istanziata da un’altra chiamata o no.

Sfruttando invece la classe Sigleton appena realizzata possiamo ovviare a questo problema come segue

public class BusinessExample {

public static BusinessInterface getBusinessInterface(String businessClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException{

BusinessInterface bus;

Singleton singleton = Singleton.getInstance();

HashMap businessClasses = singleton.getBusinessClasses();

if(businessClasses.containsKey(businessClassName)){

bus = (BusinessInterface)businessClasses.get(businessClassName);

System.out.println(“business già presente nella WM”);

}else{

Class c = Class.forName(businessClassName);

bus = (BusinessInterface)c.cast(c.newInstance());

businessClasses.put(businessClassName, bus);

System.out.println(“classe istanziata con la reflection”);

}

return bus;

}

}

La riga

Singleton singleton = Singleton.getInstance();

ci ritorna semplicemente l’unica classe Singleton istanziata, non effettua una nuova istanza, quindi tutto ciò che è stato memorizzato al suo interno precedentemente ce lo ritroveremo in qualsiasi momento,è per questo motivo che possiamo fare il controllo attraverso la IF, se la chiave è presente o meno nella HashMap businessClasses, e solo se la classe Business cercata non è stata istanziata si provvederà a farlo attraverso la Reflection

Abbiamo aggiunto solo le classi di Business nella classe Singleton, che come abbiamo visto ha assunto il ruolo di CacheManager, ma se se usata opportunamente è semplice sfruttare al meglio questa classe.

Supponiamo infatti di dover inserire in cache il nostro Logger preferito, basterà semplicemente aggiungerlo nella classe Singleton

public class Singleton {

private static Singleton singleton = null;

private static Logger logger = null;

private HashMap businessClasses = new HashMap();

private Singleton(){}

public static Singleton getInstance(){

if(singleton == null) singleton = new Singleton();

return singleton;

}

public static Logger getLogger() {

return logger;

}

public static void setLogger(Logger logger) {

Singleton.logger = logger;

}

public HashMap getBusinessClasses() {

return businessClasses;

}

public void setBusinessClasses(HashMap businessClasses) {

this.businessClasses = businessClasses;

}

}

A differenza di quanto accade sfruttando la Session, con Singleton richiamare le variabili è semplicissimo, in quanto abbiamo i metodi elencati all’interno della classe stessa, senza impazzire a ricordarci il nome dell’attributo salvato nella Session.

Spero di essere stato all’altezza delle aspettative e spero che molti adottino questa soluzione quando si troveranno dinanzi ad un problema di cache management, se non vogliamo che la Gang of Four storca il naso :) .

9 Comments

Frameworks MVC, Reflection e Pattern Business Delegate per le nostre applicazioni Java.

Design Patterns, Java, Open Source

Scenario

Spesso quando si realizza un’applicazione, in particolare applicazioni Web, se non si ricorre a tecniche di progettazione si tende a riscrivere sempre le stesse operazioni e a produrre codice ridondante, come se si stesse lavorando presso una catena di montaggio del codice.

Per fortuna Java ragiona ad oggetti e ci permette, con i giusti accorgimenti, di risparmiare “quintali di codice”.

Quello che vedremo è come ottenere, sfruttando pochi pattern semplificati e gli strumenti di base dei Framework MVC, un’applicazione scalabile, affidabile e manutenibile lato server.

Presupposti

Prima si comincia a programmare prima si vedono risultati, prima si finisce! Quale concetto più sbagliato di questo… E’ vero che si comincia prima, ma si procede male e quando si arriva alla fase conclusiva il codice è talmente intrecciato che nemmeno l’uomo ragno può aiutarvi…

Lo scopo invece deve essere quello di realizzare un sistema come fosse costituito da costruzioni Lego, dove ogni Classe/Funzionalità non è altro che un mattoncino il quale è inscindibile e da solo ha una sua funzione specifica.

Inoltre la forza di queste piccole costruzioni è che pur se piccoli quasi tutti i componenti, si legano tra di loro (ognuno con le sue caratteristiche e funzioni) per realizzare non 1 sola, ma N costruzioni diverse senza dover modificare la forma di ogni singolo elemento.

In particolar modo per questo articolo vedremo come strutturare il lato Model in livelli (layers) in modo tale da rendere la Business Logic (il core dell’applicazione) facilmente “pluggabile” indifferentemente dal framework (d’ora in poi FW) che si vorrà adottare, aiutandoci dalle funzionalità di base del controller ovvero fungere da spina dorsale del sistema collegando tra di loro la parte di presentation con la logica dell’applicazione stessa.

Hands on Head

Lo scenario con cui solitamente si lavora sui progetti utilizzanti FW MVC nella migliore delle ipotesi (non è insolito trovare programmatori che accantonano tutta la logica nelle action Struts o bean di JSF) è del tipo rappresentato in figura 1.

Analizziamo lo scenario. Per ogni coppia JSP-Action vi è associata nel controller una definizione che lega le due. A loro volta le action fanno riferimento a una o più unità Business. Ovvero abbiamo per N coppie JSP-Action N definizioni nel controller e minimo N legami Action-Business…

Questa magari per piccole applicazioni è una soluzione plausibile ma immaginate uno scenario più ampio dove ci sono centinaia di coppie e legami da definire, il codice inizierebbe a diventare poco leggibile per chiunque, e inoltre cosa succederebbe se per qualche esigenza di progetto il FW dovesse cambiare per effettuare un’integrazione o un upgrade su altre piattaforme… i costi di maintenance e gli errori sarebbero notevoli.

Lo scopo quindi, come illustrato in figura 2, è quello di sintetizzare al minimo l’utilizzo degli strumenti del FW utilizzando 1 sola definizione e 1 sola action aggiungendo un semplice ma potente livello alla nostra logica, il Business Delegator, ovvero uno smistatore “intelligente” di classi Business.

Il passo importante da considerare sta nel fatto che con l’aggiunta del nostro Delegator, lo strato di Business Logic è completamente separato e indipendente da qualsiasi FW.

Il controller di Struts permette in base alle risposte ricevute dalla Action (Interfaccia di collegamento tra il la Business Logic e il Controller) di re-indirizzare il risultato su una pagina o su un’altra definizione di Action.

Non è necessario realizzare una definizione nel controller (d’ora in poi ActionConfig) e una Action per ogni funzionalità/pagina che si vuole realizzare.

Infatti è possibile realizzare un’unica Classe di Action per tutte le funzionalità di recupero dati di cui la nostra applicazione necessita.

Come? semplice, sfruttando i Design Pattern.

In ogni ActionConfig è possibile associare una sola Action, ma per fortuna è anche possibile associare in base alla risposta, N forward a pagine (o tiles, file velocity) diverse.

Avendo un problema su 2 risolto dal FW, non ci resta che fornire alla nostra Action una classe Business con cui interloquire, un po’ più particolare delle altre, la quale avrà il compito di:

  • smistare in modo intelligente le richieste del client presso le altri classi Business
  • ritornare le risposte verso la Action.

Se qualcuno a questo punto sta immaginando, come soluzione tipo, un’infinità di if-else o switch-case è lontano dalla soluzione, perchè in questo caso la action pur essendo più veloce, sia come soluzione che come tempo di esecuzione, non avrebbe la dinamicità che un progettista deve assicurare. Una volta realizzato la classe di Action, anche se le classi di business diventeranno 10, 100 1000, 10000 il codice non deve aver bisogno di maintenance.

Ovviamente, si ha la necessità di fare un compromesso. In questo caso se vogliamo che il codice lato server sia intelligente, abbiamo bisogno di un piccolo aiuto da parte del client.il quale dovrà fornirci informazioni di base attraverso i link/form, nel nostro caso basteranno il nome del Business, il nome del metodo da chiamare, e i parametri di cui il metodo necessita.

Ipotizziamo di avere N classi di business Class1usiness.java, Class2Business.java, …, ClassNBusiness. Se non ragionassimo con le interfaccie, ogni volta in cui sia necessario istanziare una classe dovremmo per forza inserire nella nostra Action il nome della classe specifica così come mostra il codice seguente

String businessName = (String)request.getParameter(”businessName”);

ArrayList results = new ArrayList();

if(businessName.equals(”Class1Business”)){

results = new Class1Business().getResults();

} else if(businessName.equals(”Class2Business”)){

results = new Class2Business().getResults();

}

//…

else if(businessName.equals(”ClassNBusiness”)){

results = new ClassNBusiness().prendiRisultatiArrayList();

}

Inoltre, così come illustrato, non sempre i nomi dei metodi di recupero sono li stessi, soprattutto quando si è in molti a sviluppare codice sullo stesso progetto.

Già questi 3 motivi (classi/controller da aggiornare continuamente, multi if-else, nomi metodi diversi) dovrebbero scoraggiarci ad operare in questo modo. Onde evitare pensieri “troppo liberi” conviene mettere qualche paletto nel nostro (e in quello degli altri) modo di operare.

Creiamo una Factory.

Abbiamo bisogno di dare una linea guida alle nostre classi Business, quindi scriveremo un’interfaccia.

public interface BusinessInterface {

public ArrayList getResults(String methodName, Object params) throws Exception;

}

Leggiamo assieme questa semplice interfaccia. Essa necessita in input di 2 parametri, ovvero il nome del metodo che la classe business deve eseguire, un Object rappresentante il/i parametro/i da interpretare (ricordiamo che l’oggetto Object può assumere significato multiplo).

Questa interfaccia cattura e rimanda alla classe chiamante l’eventuale eccezione generata/avvenuta. Questo metodo inoltre restituisce un ArrayList di valori e il nome del metodo è getResults. In questo modo abbiamo assicurato che tutte le classe Business abbiano un metodo per la restituzione dei risultati con lo stesso nome, e non solo…

Implementando in Class1Business l’interfaccia appena creata avremo:

public class Class1Business implements BusinessInterface{

private ArrayList results = new ArrayList();

public ArrayList execute(String methodName, Object params) throws Exception {

//il nostro codice

return results;

}

}

Adesso che le nostre classi Business hanno uno standard di implementazione, abbiamo bisogno di uno strato intermedio che ci faccia da interprete tra le richieste della classe di Action e le singole classi di Business.

La Business Delegate.

Adesso abbiamo la possibilità di fare questo:

BusinessInteface businessInterface = null;

businessInterface = new Class1Business();

businessInterface = new Class2Business();

businessInterface = new ClassNBusiness();

Ovvero possiamo istanziare nella colonna di destra tutte le classi che implementano l’interfaccia.

Il nostro scopo ora è quello di implementare in modo dinamico le classi nella colonna di destra. In questo modo la nostra action potrà caricare N classi senza aver il bisogno di nessuna sorta di switch. E’ qui che entra in gioco la Reflection di Java.

BusinessDelegator.java

Class c = Class.forName(ProjectConstant.BUSINESS_PREFIX + businessName);

BusinessInterface bus = (BusinessInterface)c.cast(c.newInstance());

dove Class.forName(String className) effettua l’istanza della classe dato il suo nome, e BUSINESS_PREFIX non è altro che una costante di progetto con valore org.solimena.corsojava.business (nel nostro caso), mentre businessName è il nome della classe Business fornita, come dicevamo prima, dal Client,. Giusto per chiarezza prendiamo il caso in cui dal client sia arrivata la richiesta di utilizzare i servizi della classe Class7Business.

Dinamicamente il compilatore interpreterà il comando come

Class c = Class.forName(”org.solimena.corsojava.business.Class7Business”);

BusinessInterface bus = (BusinessInterface)c.cast(c.newInstance());

La prima riga di codice effettua un’istanza della classe org.solimena.corsojava.business.Class7Business, mentre la seconda effettua un casting della classe a BusinessInterface.

Questo è il core del nostro Delegator, poichè tutti i BusinessObject implementano l’interfaccia BusinessInterface e quindi il casting è concesso.

L’utilizzo della Reflection ovviamente è un pò più lento rispetto ad istanziare al volo una classe, ma come iniziate a capire i benefici sono notevoli

// tempo 16ms

Class7Business bus = new Class7Business();

// tempo 31ms

Class c = Class.forName(”org.solimena.corsojava.business.Class7Business”);

BusinessInterface bus = (BusinessInterface)c.cast(c.newInstance());

Vediamo al completo la nostra classe di Business Delegate.

public class BusinessDelegator {

public static ArrayList getResults(String businessName, String methodName, Object params) throws ClassNotFoundException, IllegalAccessException, InstantiationException, Exception{

Class c = Class.forName(ProjectConstant.BUSINESS_PREFIX + businessName);

BusinessInterface bus = (BusinessInterface)c.cast(c.newInstance());

//recuperiamo i risultati del Business

ArrayList results = bus.getResults(methodName, params);

return result;

}

}

Ovviamente è stata inserita la parte finale del nostro delegator, ovvero richiamare il metodo getResults appartenente a tutti i Business implementanti l’interfaccia BusinessInterface, e ritornare al chiamante la risposta recuperata dal Business desiderato.

Adesso abbiamo tutti gli strumenti per scrivere un’unica classe di Action.

package org.solimena.corsojava.presentation.action;

import …;

public class BuilderAction extends Action {

private String result = “”;

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {

//preleviamo dal client le richieste

String businessName = (String)request.getParameter(”businessName”);

String methodName = (String)request.getParameter(”methodName”);

Object params = request.getParameter(”params”);

//effettuiamo un controllo sull’esistenza dei parametri fondamentali fortiti dal client

if(businessName != null && !businessName.equals(”") && methodName != null && !methodName.equals(”")){

ArrayList results = new ArrayList();

try {

// Delegator

results = BusinessDelegator.getResults(businessName, methodName, params);

// Fine Delegator

request.setAttribute(”matrix”, results);

result = businessName + “_” + methodName.split(”,”)[0];

} catch (Exception e) {

request.setAttribute(”errore”, “Exception -> ” + e.getMessage());

result = “failure”;

e.printStackTrace();

}

}

return mapping.findForward(result);

}

}

Con l’aggiunta di appena un’interfaccia ed una classe la nostra applicazione ha acquisito la dinamicità che cercavamo diminuendo drasticamente i tempi di sviluppo (se pur aumentando sensibilmente quello di esecuzione).

La differenza rispetto all’approccio iniziale della nostra classe di Action è veramente sostanziale, in quanto adesso viene usata unicamente come punto di incontro tra la logica ed il controller.

Il nome Matrix della request.setAttribute non è a caso, in quanto quello che viene salvato è una matrice di valori (potreste realizzare i metodi Business in modo che tornino degli ArrayList di HashMap ad esempio).

Attraverso politiche di loop all’interno delle pagine JSP sarà possibile recuperare i dati memorizzati all’interno della nostra matrice.

La riga

result = businessName + “_” + methodName.split(”,”)[0];

viene utilizzata allo scopo di far capire al nostro controller a quale forward deve essere associata la risposta.

Vediamo adesso come comparirà il nostro Controller.

<action

path=”/recuperoDati”

type=”org.solimena.corsojava.presentation.action.BuilderAction”

>

<forward name=”Class1Business_findAll” path=”/pages/visualizzaTuttiGliOggetti.jsp” />

<forward name=”Class1Business_findById” path=”/pages/visualizzaDettaglioOggetto.jsp” />

<forward name=”Class4Business_Method1″ path=”/pages/funzionalita1.jsp” />

<forward name=”failure” path=”/pages/failure.jsp” />

</action>

Così come si vede, vi è una sola classe di Action associata, mentre le classi di forward sono N.

Ovviamente un URL tipo avrà la seguente forma

http://[NomeServer]:[porta]/[NomeApplicazione]/[NomeActionConfig].[estensione]?businessName=[NomeBusiness]& methodName=[NomeMetodo]&params=[valori separati da comma]

per esempio:

http://localhost:8080/corsojava/recuperoDati.do?businessName=Class1Business&methodName= findById&params=7

In questo modo abbiamo assicurato che la logica di recupero e smistamento dati sia demandata al server, come anche la distribuzione dell’output alla relativa pagina di presentation, il tutto in base ai dati forniti dal client, (comodo no?), così se dovesse cambiare il FW, anche i link rimarrebbero invariati.

Conclusione

Avevamo detto all’inizio che avremmo realizzato un’applicazione estensibile, affidabile e manutenibile, vediamo assieme i miglioramenti apportati.

  • Estensibile: Seguendo la logica del Low Coupling(Basso Accoppiamento tra le classi) l’applicazione è stata suddivisa in Layer dove ogni strato dialoga unicamente con il livello superiore e con quello sottostante e ogni classe ha le sue funzionalità specifiche che le altre non hanno. Necessitando in futuro di estensioni la nostra applicazione di base resterà pressoché invariata.
  • Affidabile: gestione delle eccezioni e nomenclatura consolidata, inoltre
  • Manutenibile: abbiamo abolito le classi tuttofare per fare posto a classi leggere, facilmente leggibili e documentabili, con degli standard associati, inoltre anche lo strato Presentation è preservato. In fase di test avendo a che fare con molte classi, ma estremamente semplici, è facile (e quindi veloce) intervenire sul problema senza compromettere l’integrità dell’applicazionie

Ovviamente la gestione delle eccezioni è una parte fondamentale su cui andrebbero scritti numerosi articoli, qui è stato dato solo lo spunto di ragionamento catturando l’eccezione generica Exception ma è ovvio che le eccezioni vanno gestite e vanno gestite tutte per realizzare un sistema affidabile.

A questo punto al di là che usiate o no framework MVC, usando 1 o N ActionConfig (nel caso raro in cui lo stesso metodo di una classe Business sia associato a più pagine), o che usiate a delle servlet, oppure delle semplici JSP, utilizzare il pattern Business Delegate è di fondamentale importanza. Introducendo questo concetto nei vostri progetti vi verrà facile utilizzarlo al meglio.

PRO

  • nei grandi progetti la suddivisione a strati rende le classi e il lavoro del team meglio organizzato.
  • interfaccia unica per N classi di business con gestione delle eccezioni
  • chiamata alle classi Business dinamica
  • nessuna classe tuttofare, assicurati i principi di alta coesione/basso accoppiamento
  • basso accoppiamento con il FW

CONTRO

  • costo computazionale superiore (31ms contro i 16ms)

14 Comments

Model Driven Architecture e sviluppo J2EE

Design Patterns

Abbreviato con MDA, il Model Driven Architecture è un approccio allo sviluppo di applicativi che ha radici già nel lontano 2004.

Di cosa si tratta ? E’ sostanzialmente un’Architettura del Processo di Sviluppo del Software, standardizzata dall’OMG, basata sulla modellazione UML e sulla separazione in livelli diversi di astrazione. Un manuale dell’OMG è disponibile quì.

Secondo l’approccio MDA, lo sviluppo di un sistema avviene attraverso la modellazione a due livelli:

  • livello PIM (Platform Indipent Model), modellazione UML dell’applicativo indipendente dalla piattaforma su cui sarà ospitato (uso di Design Pattern e Design by Contract)
  • livello PSM (Platform Specific Model), modellazione UML dell’applicativo caratterizzata dalla piattaforma software da usare (es WS, EJB, J2EE, .NET)

Con tale divisione, si ottengono alcuni evidenti vantaggi:

  • la suddivisione netta del lavoro fra la progettazione UML del business basato sull’analisi funzionale (modelli PIM) e la modellazione analitica del sistema basata sull’analisi tecnica (modelli PSM)
  • riuso del modello funzionale grazie all’indipendenza con i modelli tecnologici
  • disaccoppiamento forte tra funzionalità e tecnologia: separation of concern
  • migliore separazione dei ruoil, l’esperto del dominio non necessariamente deve essere esperto delle tecnologie

Alcuni aritoli interessanti sull’argomento:

Tutta questa teoria non sarebbe nulla se poi qualche folle non si fosse messo d’intento a realizzare qualche tool che permetta:

  • la modellazione visuale UML dei modelli PIM e PSM
  • la generazione automatica del codice dai modelli PIM e PSM
  • intercambiabilità della tecnologia da usare (Cartridge) per la generazione del codice (es. JSP/JSF/STRUTS-SPRING-HIBERNATE oppure ASP.NET-ASMX-NHibernate)

Qualche tool ho recensito:

  • AndroMDA, applicativo stand-alone a riga di comando basato su modelli UML prodotto da IDE in grado di esportare UML in formato XMI (es. ArgoUML e StarUML), ha diverse Cartidge sia in ambiente Java che .NET
  • Taylor, plugin per Eclipse che permette anche la modellazione UML, ha una sola Cartridge basata su EJB-JSF-JBOSS Seam
  • OptimalJ, ambiente per la modellazione UML e la generazione del codice per piattaforma J2EE, putroppo non OpenSource di Compuware

Ora vi ho detto tutto … buon divertimento e sentiamoci se sperimentate qualcosa in tal senso …

mi interesserebbe sapere se avete fatto esperienze sui framework che permettono lo sviluppo veloce di soluzioni complete per piattaforma J2EE.

6 Comments

Introduzione ai Patterns

Design Patterns

Ciao ragazzi, come promesso ecco qui una piccola introduzione sui pattern: che cosa sono? ed in che modo possono aiutarci a scrivere codice migliore? I pattern sono sostanzialmente delle soluzioni standard a delle problematiche frequenti in campo software. Queste soluzioni sono inserite all’interno di un contesto nel quale viene spiegata la problematica, viene spiegata la soluzione al problema e come ci si è arrivati, e viene fornito un esempio pratico di applicazione della soluzione. L’insieme di questi elementi costituisce quindi un “percorso” che il programmatore può seguire per giungere a una soluzione che sia garanzia di affidabilità, in quanto applicata e testata più volte in altri ambiti.
I pattern della Gang of Four si basano pesantemente sulla programmazione orientata agli oggetti e mirano a migliorare la qualità del codice agendo su caratteristiche legate ad essa. Ad esempio mirano ad aumentare la riusabilità del codice, ad aumentare il livello di incapsulamento delle informazioni di un oggetto e a diminuire il livello di coesione tra oggetti di classi differenti. Questo modo di operare porta alla costituzione di una serie di “mattoncini” di codici riutilizzabili nelle situazioni più diverse, operando solamente un minimo riadattamento.
Bene ragazzi, l’introduzione può bastare…ora sotto a chi tocca, e spero che tutti parteciperete a questa sezione, anche con esempi concreti.
Ciao Renato

No Comments

Design Patterns

Design Patterns

Ciao ragazzi, inauguro oggi una sezione che credo interesserà a tutti quanti: Design Patterns. Fino ad un anno e mezzo fa, non sapevo neanche cosa fossero, ed invece oggi sono uno degli argomenti di mio grande interesse e che vorrei tanto approfondire, naturalmente con il vostro contributo. E’ una idea che era venuta insieme ai miei due colleghi Luca e Salvatore, solo che non avevo mai avuto il tempo di realizzarla: inizio oggi. Il primo articolo sarà una breve introduzione ai patterns, ed al loro utilizzo, seguiranno poi uno dopo l’altro i 23 patterns presenti oggi sul libro della “Gang of Four”: “DESIGN PATTERNS: ELEMENTS OF REUSABLE OBJECT-ORIENTED SOFTWARE”. Ciao a tutti, e spero che tutti parteciperete a questa nuova sezione tecnologica.
Ciao Renato

2 Comments


  • Google Adsense

  • MiniBlog

    Banner Javaday Roma III Edizione >>

    Adobe ha appena sfornato il Flash player nella versione 10, stavolta anche per Linux da subito! Incredibile >>

    When the source code to Quake was leaked and circulated among the Quake community underground in 1996, a programmer unaffiliated with id Software used it to port Quake to Linux, and subsequently sent the patches to Carmack. Instead of pursuing legal action, id Software, at Carmack’s behest, used the patches as the foundation for a company-sanctioned Linux port. id Software has since publicly released the source code to Quake, Quake 2 and most recently Quake 3, all under the GNU General Public License (GPL). >>

    Ganymede Donate, please ;) >>

    Download Day 2008 >>

    Scusa Ameri, Sun s’è comprata MySQL e Oracle s’è pappata BEA. >>

    Chi ha bisogno di un Mac quando con Linux abbiamo Compiz, Open Office, Inkscape, Scribus, Eclipse, Tracker, ed ora anche una Time Machine per recuperare al volo vecchi backup? Per ora manca lo sberluccichio di casa Apple ma il funzionamento è analogo: si chiama FlyBack! >>

    Giusto per ricordarvi che una delle distribuzioni Linux più diffuse sta per raggiungere le nostre scrivanie :D

    >>

    Anche se me ne vergogno come un ladro non posso esimermi dal pubblico ludibrio consentendovi di ritrovare tracce di me nella storia di Internet: era il 6 Ottobre 1995 ed il 4 Novembre 1995. E come non ricordare la mia prima Home Page>>

    Assegnati gli Ig Nobel per la ricerca improbabile qui e, appena possibile, qui. >>

  • Categories