27
Giuseppe Dell'Abate's Blog Java Tips and Tricks Home Corsi Libri About Type text to search here... Home > GOF Pattern , java > GoF Patterns: Visitor GoF Patterns: Visitor 2 aprile 2013 Giuseppe Dell'Abate Lascia un commento Go to comments Translate in English with Google Translate In questo articolo tratterò il pattern Visitor Motivazione Si tratta di un pattern comportamentale basato su oggetti e viene utilizzato per eseguire delle operazioni sugli elementi di una struttura. L’utilizzo di questo pattern consente di definire le operazioni di un elemento senza doverlo modificare. Ma com’è possibile? Non mi riferisco alla tecnica di decorazione, trattata in un articolo precedente , ma mi riferisco ad un’altra tecnica di “arricchimento” del codice. Solitamente ogni classe definisce le proprie proprietà e le proprie operazioni nel rispetto del principio della singola responsabilità (SRP) ed usando il concetto di ereditarietà può condividere le operazioni alle classi figlie. Ma cosa succede se ci accorgiamo a posteriori che dobbiamo introdurre una nuova operazione? Se le operazioni sono state definite a livello di classe, l’introduzione di un nuovo metodo comporterà la modifica della classe interessata, violando il principio open-closed (OCP). Se le operazioni sono state definite a livello di interfaccia, l’introduzione di un nuovo metodo comporterà la modifica di tutte le classi figlie. Ovviamente se questa situazione si presenta frequentemente, la manutenzione del codice non sarà agevole. Per evitare questo problema sarà possibile seguire un’altra strada, ossia disaccoppiare gli oggetti che definiscono lo stato dagli oggetti che definiscono il comportamento ed in questo modo sarà più semplice inserire nuovi metodi. Il pattern Visitor ci consente di implementare questa separazione tra stato e comportamento e realizzare il legame tra questi oggetti tramite la definizione di 2 metodi presenti nelle due strutture. 1. Nella prima struttura, che definisce lo stato, è presente il metodo accept() che invoca il metodo visit() 2. Nella seconda struttura, che definisce il comportamento, è presente il metodo visit() In questo modo sarà possibile aggiungere nuove operazioni semplicemente definendo nuove classi nella

GoF Patterns: Visitor | Giuseppe Dell'Abate's Blog

Embed Size (px)

DESCRIPTION

Visitor Pattern - Extract from Giuseppe Dell'Abate's Blog

Citation preview

  • Giuseppe Dell'Abate's BlogJava Tips and Tricks

    HomeCorsiLibriAbout

    Type text to search here... Home > GOF Pattern, java > GoF Patterns: Visitor

    GoF Patterns: Visitor2 aprile 2013 Giuseppe Dell'Abate Lascia un commento Go to commentsTranslate in English with Google TranslateIn questo articolo tratter il pattern VisitorMotivazioneSi tratta di un pattern comportamentale basato su oggetti e viene utilizzato per eseguire delle operazionisugli elementi di una struttura. Lutilizzo di questo pattern consente di definire le operazioni di unelemento senza doverlo modificare.Ma com possibile?Non mi riferisco alla tecnica di decorazione, trattata in un articolo precedente, ma mi riferisco ad unaltratecnica di arricchimento del codice.Solitamente ogni classe definisce le proprie propriet e le proprie operazioni nel rispetto del principiodella singola responsabilit (SRP) ed usando il concetto di ereditariet pu condividere le operazioni alleclassi figlie.Ma cosa succede se ci accorgiamo a posteriori che dobbiamo introdurre una nuova operazione?

    Se le operazioni sono state definite a livello di classe, lintroduzione di un nuovo metodocomporter la modifica della classe interessata, violando il principio open-closed (OCP).Se le operazioni sono state definite a livello di interfaccia, lintroduzione di un nuovo metodocomporter la modifica di tutte le classi figlie.

    Ovviamente se questa situazione si presenta frequentemente, la manutenzione del codice non saragevole.Per evitare questo problema sar possibile seguire unaltra strada, ossia disaccoppiare gli oggetti chedefiniscono lo stato dagli oggetti che definiscono il comportamento ed in questo modo sar pi sempliceinserire nuovi metodi.Il pattern Visitor ci consente di implementare questa separazione tra stato e comportamento e realizzare illegame tra questi oggetti tramite la definizione di 2 metodi presenti nelle due strutture.

    1. Nella prima struttura, che definisce lo stato, presente il metodo accept() che invoca il metodovisit()

    2. Nella seconda struttura, che definisce il comportamento, presente il metodo visit()In questo modo sar possibile aggiungere nuove operazioni semplicemente definendo nuove classi nella

  • seconda struttura che si occuper poi di elaborare lo stato della prima.Vediamo la rappresentanzione UML usando il Class Diagram:

    Visitor BasePertanto, parlando in termini del pattern Visitor:In base alla competenza:

    1. la prima struttura definisce gli Element che detengono lo stato2. la seconda struttura definisce i Visitor che detengono i comportamenti

    In base allordine di invocazione:1. Il Client invoca il metodo accept() presente nellElement passandogli in ingresso un oggetto Visitor2. LElement invoca il metodo visit() del Visitor passandogli se stesso (oggetto this) come parametro.3. Il Visitor, disponendo della referenza allElement (tramite loggetto this) accede alle propriet

    dellElement ed eseguire le operazioni.Vediamo la rappresentanzione UML usando il Sequence Diagram:

    Simple Visitor InteractionQuesto pattern utilizza la tecnica del Double Dispatch, che ho trattato in un articolo precedente, al fine di

  • consentire questo scambio di messaggi tra lElement ed il Visitor, pertanto risulta un po complessoconsiderando che utilizza polimorfismo, overriding ed overloading.Partecipanti e StrutturaQuesto pattern composto dai seguenti partecipanti:

    Element: definisce il metodo accept() che prende un Visitor come argomentoConcreteElement: implementa un oggetto Element che prende un Visitor come argomentoObjectStructure: contiene una collezione di Element che pu essere visitata dagli oggetti VisitorVisitor: dichiara un metodo visit() per ogni Element; il nome del metodo ed il parametroidentificano la classe Element che ha effettuato linvocazione.ConcreteVisitor: implementa il metodo visit() e definisce lalgoritmo da applicare per lElementpassato come parametro

    Vediamo come si presenta il Pattern Visitor utilizzando il Class Diagram in UML:

    Visitor Pattern StructureConseguenzeTale pattern presenta i seguenti vantaggi/svantaggi:

    Facilit nellaggiungere nuovi Visitor: definendo un nuovo Visitor sar possibile aggiungere unanuova operazione ad un ElementDifficolt nellaggiungere nuovi Element: definire un nuovo Element comporter la modificadellinterfaccia Visitor e di tutte le implementazioniSeparazione tra stato ed algoritmi: gli algoritmi di elaborazioni sono nascosti nelle classi Visitor enon vengono esposti nelle classi Element.Iterazione su struttura eterogenea: la classe Visitor in grado di accedere a tipi diversi, senza la

  • necessit che tra di essi ci sia un vincolo di parentela. In poche parole, il metodo visit() pu definirecome parametro un tipo X oppure un tipo Y senza che tra di essi ci sia alcuna relazione di parentela,diretta o indiretta.Accumulazione dello stato: un Visitor pu accumulare delle informazioni di stato a seguitodellattraversamento degli Element.Violazione dellincapsulamento: i Visitor devono poter accedere allo stato degli Element e questopu comportare la violazione dellincapsulamento.

    ImplementazioneIl pattern Visitor suscita sensazioni di odio-amore (qui o qua) e ci molto comprensibile a causa dellasua complessit e dei suoi limiti. Inoltre non semplice identificare la casistica in cui utilizzarlo anche afronte del fatto che, se le specifiche cambiano, questo pattern resta molto faraginoso da mantenere.Partendo da questa premessa si capisce che non sar semplice spiegarlo pertanto utilizzer un approccioincrementale, partendo da un esempio semplice per poi complicarlo. Nella sua forma pi semplice questopattern esprime semplicemente il Double Dispatch che ne costituisce la sua natura che occorrer rivedere.Inoltre occorre osservare che questo pattern stato oggetto di proposte di rivisitazione, ma in questocontesto mi limiter ad usarlo nella sua forma originaria.Come esempio, ho pensato a queste implementazioni:

    1. Hello Visitor: semplice esempio che ha lo scopo di introdurre il Double Dispatch2. Calcolo dellaria del rettangolo: 1 elemento ed 1 algoritmo3. Calcolo del perimetro del rettangolo: 1 elemento e 2 algoritmi4. Calcolo dellaria e del perimetro del triangolo: 2 elementi e 4 algoritmi5. Calcolo dellaria e del perimetro del triangolo, ciclando una lista: 2 elementi e 4 algoritmi

    1. Hello VisitorPer iniziare riprendo lesempio fatto allinizio, il pi semplice possibile, al fine di invocare uncomportamento, definito in una classe Visitor, su di uno stato, definito in una classe Element. Un sempliceHello Visitor!.Definiamo la classe Element che definisce lo stato (propriet hello), laccessor (metodo getHello()) ed ilcollegamento con il Visitor(metodo accept()):

    Definiamo la classe Visitor che definisce la modalit di interfacciamento con lElement (metodo visit())che, accettando come paramentro loggetto Element, sar in grado di recuperare lo stato dellElementtramite il suo accessor (metodo getHello())

    123456789

    10111213

    package patterns.visitor.hello; public class Element { private String hello = "Element"; public String getHello() { return hello; } public void accept(Visitor visitor) { visitor.visit(this); }}

    1234

    package patterns.visitor.hello; public class Visitor {

  • Per simulare la loro interazione definiamo la classe Client che si occupa di invocare lElement passando almetodo accept() il Visitor che definisce il comportamento da adottare.

    Lesecuzione del codice ha come risultato:

    2.Calcolo dellaria del rettangoloPassiamo adesso ad un esempio pi utile, ma non troppo (altrimenti diventa complicato), ossia comecalcolare larea di un rettangolo.Vediamo come si presenta il pattern in UML in base allesempio:

    Aria RettangoloVediamo come si presenta il Sequence Diagram in UML in base allesempio:

    56789

    public void visit(Element element) { System.out.println( "Hello " + element.getHello()); } }

    123456789

    10

    package patterns.visitor.hello; public class Client { public static void main(String[] args) { Element element = new Element(); element.accept( new Visitor() ); } }

    12

    $JAVA_HOME/bin/java patterns.visitor.hello.ClientHello Element

  • Definiamo la classe ElementRettangolo che detiene le informazioni dello stato del rettangolo ( ossiaaltezza e larghezza), i metodi accessor e mutator (ossia i get() e set() ) ed il metodo di accesso e di dialogocon il Visitor (metodo accept())

    Definiamo la classe VisitorRettangoloAria che definisce il metodo visitRettangoloAria() che vieneutilizzato per calcolare larea del rettangolo e che verr invocato dal metodo accept() dellelementElementRettangolo.

    123456789

    101112131415161718192021222324252627

    package patterns.visitor.rettangolo.aria; public class ElementRettangolo { private int altezza; private int larghezza; public int getAltezza() { return this.altezza; } public void setAltezza(int altezza) { this.altezza = altezza; } public int getLarghezza() { return this.larghezza; } public void setLarghezza(int larghezza) { this.larghezza = larghezza; } public void accept(VisitorRettangoloAria visitor) { visitor.visitRettangoloAria(this); }}

  • Definiamo la classe Client che setta le propriet del rettangolo, ossia il suo stato, e poi si avvale delVisitor, VisitorRettangoloAria, per calcolare la sua area.

    Eseguiamo il nostro Client e verifichiamo.

    3.Calcolo del perimetro del rettangolo.Adesso ampliamo lesempio fatto precedentemente inserendo una nuova operazione. In questo casomodifichiamo la struttura dellesempio per avvicinarci sempre pi alla struttura del pattern.

    12345678

    package patterns.visitor.rettangolo.aria; public class VisitorRettangoloAria { public void visitRettangoloAria(ElementRettangolo elementRettangolo) { int aria = elementRettangolo.getAltezza() * elementRettangolo.getLarghezza(); System.out.println("L'area del rettangolo e': " + aria); }}

    123456789

    10

    package patterns.visitor.rettangolo.aria; public class Client { public static void main(String[] args) { ElementRettangolo elementRettangolo = new ElementRettangolo(); elementRettangolo.setAltezza(10); elementRettangolo.setLarghezza(20); elementRettangolo.accept( new VisitorRettangoloAria() ); }}

    12

    $JAVA_HOME/bin/java patterns.visitor.rettangolo.aria.ClientL'area del rettangolo e': 200

  • Aria e Perimetro RettangoloVediamo come si presenta il Sequence Diagram in UML in base allesempio:

  • Dobbiamo definire una classe padre dei Visitor, che prima non avevamo, al fine di definire tutte leoperazioni presenti.In particolare abbiamo le operazioni relative al calcolo dellaria e del perimetro del rettangolo.

    Di seguito dobbiamo relazionare la classe VisitorRettangoloAria con il padre e definire entrambi i metodi.Ovviamente il metodo relativo al calcolo del perimetro non dovr essere implementato.

    123456789

    package patterns.visitor.rettangolo.ariaPerimetro; abstract class Visitor { public abstract void visitRettangoloAria(ElementRettangolo elementRettangolo); public abstract void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo); }

    123456789

    package patterns.visitor.rettangolo.ariaPerimetro; public class VisitorRettangoloAria extends Visitor { @Override public void visitRettangoloAria(ElementRettangolo elementRettangolo) { int aria = elementRettangolo.getAltezza() * elementRettangolo.getLarghezza(); System.out.println("L'area del rettangolo e': "+ aria); }

  • Adesso definiamo laltro Visitor, VisitorRettangoloPerimetro, che si occupa di calcolare il perimentro delrettangolo. Come nel caso precedente, dobbiamo prevedere entrambi i metodi ma dobbiamo implementaresolo quello di interesse: visitRettangoloPerimetro.

    Adesso nella classe Element, ElementRettangolo, definiamo un comportamento diverso a secondadelloggetto passato come paramentro al metodo accept(). Poi vedremo come questa sezione pu esseremigliorata.

    10111213141516

    @Override public void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo) { throw new UnsupportedOperationException("Not supported."); } }

    123456789

    10111213141516

    package patterns.visitor.rettangolo.ariaPerimetro; public class VisitorRettangoloPerimetro extends Visitor { @Override public void visitRettangoloAria(ElementRettangolo elementRettangolo) { throw new UnsupportedOperationException("Not supported."); } @Override public void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo) { int perimentro = (elementoRettangolo.getAltezza() + elementoRettangolo.getLarghezza())* System.out.println("Il perimetro del rettangolo e': " + perimentro ); } }

    123456789

    10111213141516171819202122

    package patterns.visitor.rettangolo.ariaPerimetro; public class ElementRettangolo { private int altezza; private int larghezza; public int getAltezza() { return this.altezza; } public void setAltezza(int altezza) { this.altezza = altezza; } public int getLarghezza() { return this.larghezza; } public void setLarghezza(int larghezza) { this.larghezza = larghezza; }

  • Infine nella classe Client possiamo invocare il nostro Client che si occupa di creare il rettangolo esuccessivamente di invocare le operazioni relative al calcolo dellaria e del perimetro in base al tipo diVisitor che viene passato.

    Vediamo loutput del nostro codice.

    4.Inserimento Triangolo e calcolo dellaria e perimetroIn questo esercizio introduciamo un altro elemento, il triangolo.Lintroduzione di un elemento nuovo causa pi cambiamenti rispetto allintroduzione di un nuovoalgoritmo/operazione.

    lintroduzione di una nuova operazione comporta la creazione di una nuova classe Visitor che dovrimplementare tutte le operazioni dichiarate nellinterfaccia.lintroduzione di un nuovo elemento comporta lintroduzione di una nuova operazionenellinterfaccia Visitor pertanto la modifica di tutti i Visitor, violando anche il principio Open-Closed.

    Vediamo il tutto introducendo un nuovo elemento e nuove operazioni dichiarate nellinterfaccia Visitor.Vediamo come si presenta il Class Diagram UML

    232425262728293031

    public void accept(Visitor visitor) { if (visitor instanceof VisitorRettangoloAria) visitor.visitRettangoloAria(this); else if (visitor instanceof VisitorRettangoloPerimetro) visitor.visitRettangoloPerimetro(this); } }

    123456789

    10111213

    package patterns.visitor.rettangolo.ariaPerimetro; public class Client { public static void main(String[] args) { ElementRettangolo elementRettangolo = new ElementRettangolo(); elementRettangolo.setAltezza(10); elementRettangolo.setLarghezza(20); elementRettangolo.accept( new VisitorRettangoloPerimetro() ); elementRettangolo.accept( new VisitorRettangoloAria() ); } }

    123

    $JAVA_HOME/bin/java patterns.visitor.rettangolo.ariaPerimetro.ClientIl perimetro del rettangolo e': 60L'area del rettangolo e': 200

  • Triangolo e RettangoloVediamo come si presenta il Sequence Diagram in UML in base allesempio:

  • LElementTriangoloRettangolo prevede nel proprio metodo accept() la redirezione verso i metodi dicalcolo dellaria o del perimetro. Questo ha fatto si che si sono dovuti inserire 2 nuove operazioninellinterfaccia Visitor e ci ha comportato la modifica di tutti i Visitor.

    123456789

    10111213141516171819202122232425

    package patterns.visitor.triangolo; public class ElementTriangoloRettangolo extends Element{ private int base; private int altezza; public int getBase() { return base; } public void setBase(int base) { this.base = base; } public int getAltezza() { return altezza; } public void setAltezza(int altezza) { this.altezza = altezza; } @Override public void accept(Visitor visitor) {

  • Vediamo come si presenta linterfaccia Visitor a seguito dellinserimento dei metodi invocati dal nuovoElement:

    Vediamo limplementazione dei nuovi Visitor:il primo Visitor

    ed il secondo Visitor

    26272829303132

    if (visitor instanceof VisitorTriangoloRettangoloAria) visitor.visitTriangoloRettangoloAria(this); else if (visitor instanceof VisitorTriangoloRettangoloPerimetro) visitor.visitTriangoloRettangoloPerimetro(this); } }

    123456789

    101112

    package patterns.visitor.triangolo; public abstract class Visitor { public abstract void visitRettangoloAria(ElementRettangolo elementRettangolo); public abstract void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo); public abstract void visitTriangoloRettangoloAria(ElementTriangoloRettangolo elementTriangoloRettangolo); public abstract void visitTriangoloRettangoloPerimetro(ElementTriangoloRettangolo elementoTriangoloRettangolo);}

    123456789

    1011121314151617181920212223242526

    package patterns.visitor.triangolo; public class VisitorTriangoloRettangoloAria extends Visitor { @Override public void visitRettangoloAria(ElementRettangolo elementRettangolo) { throw new UnsupportedOperationException("Not supported."); } @Override public void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo) { throw new UnsupportedOperationException("Not supported."); } @Override public void visitTriangoloRettangoloAria(ElementTriangoloRettangolo elementTriangoloRettangolo) { int aria = ((elementTriangoloRettangolo.getBase() * elementTriangoloRettangolo.getAltezza())/ System.out.println("L'area del triangolo e': " + aria); } @Override public void visitTriangoloRettangoloPerimetro(ElementTriangoloRettangolo elementoTriangoloRettangolo) { throw new UnsupportedOperationException("Not supported."); } }

  • Il Client di seguito invocher entrambi gli Element:

    Loutput del Client e il seguente:

    123456789

    1011121314151617181920212223242526

    package patterns.visitor.triangolo; public class VisitorTriangoloRettangoloPerimetro extends Visitor { @Override public void visitRettangoloAria(ElementRettangolo elementRettangolo) { throw new UnsupportedOperationException("Not supported yet." } @Override public void visitRettangoloPerimetro(ElementRettangolo elementoRettangolo) { throw new UnsupportedOperationException("Not supported yet." } @Override public void visitTriangoloRettangoloAria(ElementTriangoloRettangolo elementTriangoloRettangolo) { throw new UnsupportedOperationException("Not supported yet." } @Override public void visitTriangoloRettangoloPerimetro(ElementTriangoloRettangolo elementTriangoloRettangolo) { int perimetro = (elementTriangoloRettangolo.getBase() + (elementTriangoloRettangolo.getAltezza()* System.out.println("Il perimetro del triangolo e': " + perimetro ); } }

    123456789

    10111213141516171819

    package patterns.visitor.triangolo; public class Client { public static void main(String[] args) { ElementRettangolo elementRettangolo = new ElementRettangolo(); elementRettangolo.setAltezza(10); elementRettangolo.setLarghezza(20); elementRettangolo.accept( new VisitorRettangoloPerimetro() ); elementRettangolo.accept( new VisitorRettangoloAria() ); ElementTriangoloRettangolo elementTriangoloRettangolo = new elementTriangoloRettangolo.setBase(10); elementTriangoloRettangolo.setAltezza(20); elementTriangoloRettangolo.accept( new VisitorTriangoloRettangoloPerimetro()); elementTriangoloRettangolo.accept( new VisitorTriangoloRettangoloAria()); } }

    1234

    $JAVA_HOME/bin/java patterns.visitor.triangolo.ClientIl perimetro del rettangolo e': 60L'area del rettangolo e': 200Il perimetro del triangolo e': 50

  • 5.Inserimento di una classe di Aggregazione e calcolo dellaria e perimetroIn questo esercizio completiamo il pattern inserendo lultimo elemento: ObjectStructure che contienelelenco degli elemento che dovranno essere invocatiVediamo come si presenta il Class Diagram UML

    Vediamo come si presenta il Sequence Diagram UML

    5 L'area del triangolo e': 100

  • In questo caso la modifica consiste nellintroduzione della classe Struttura che avr il compito diinizializzare ed invocare gli elementi contenuti nella propria lista. Vediamo meglio:

    123456789

    1011121314151617181920212223242526

    package patterns.visitor.triangolo; import java.util.Iterator;import java.util.Vector; public class Struttura extends Vector { public Struttura(){ ElementRettangolo elementRettangolo = new ElementRettangolo(); elementRettangolo.setAltezza(10); elementRettangolo.setLarghezza(20); add( elementRettangolo); ElementTriangoloRettangolo elementTriangoloRettangolo = new elementTriangoloRettangolo.setBase(10); elementTriangoloRettangolo.setAltezza(20); add( elementTriangoloRettangolo ); } public void esegui() { Iterator iterator = this.iterator(); while( iterator.hasNext()){ Element element = (Element) iterator.next(); element.accept(new VisitorRettangoloAria()); element.accept(new VisitorRettangoloPerimetro()); element.accept(new VisitorTriangoloRettangoloAria());

  • In questo caso il Client si presenta pi snello in quanto deve semplicemente invocare la classe Struttura,che per noi funge da Facade:

    Loutput del Client e il seguente:

    27282930

    element.accept(new VisitorTriangoloRettangoloPerimetro()); } }}

    123456789

    10

    package patterns.visitor.triangolo; public class Client { public static void main(String[] args) { Struttura struttura = new Struttura(); struttura.esegui(); } }

    12345

    $JAVA_HOME/bin/java patterns.visitor.triangolo.ClientL'area del rettangolo e': 200Il perimetro del rettangolo e': 60L'area del triangolo e': 100Il perimetro del triangolo e': 50

    You May Like1.

    You May Like1.

    About these ads

  • Share this:

    Twitter 1 E-mail Facebook 4 Stampa LinkedIn 4 Print & PDF

    Categorie: GOF Pattern, javaCommenti (4) Trackbacks (0) Lascia un commento Trackback

    You May Like1.

    Roma - AlgheroSolo andata

    SCEGLI 77

    Firenze - AlgheroSolo andata

    SCEGLI 126

    Milano - AlgheroSolo andata

    SCEGLI 83

    Mi piaceDi' per primo che ti piace.

    Articoli collegati

    GoF Patterns: Abstract Factory GoF Patterns: Interpreter Tell, don't Ask

    GoF Patterns: Abstract Factory GoF Patterns: Interpreter Tell, don't Ask

    In "GOF Pattern" In "GOF Pattern" In "java"

    In "GOF Pattern" In "GOF Pattern" In "java"

  • 1. Alessandro15 luglio 2013 alle 12:12 AMRispondi

    Ciao! Grazie per la spiegazione esauriente! davvero utile. Sapresti indicarmi qualche fonte perinformazioni pi approfondite sullargomento?Ps. Nellesempio 1. Hello Visitor perch il metodo getHello() definito come mutator e non comeaccessor?

    Giuseppe Dell'Abate15 luglio 2013 alle 11:01 AMRispondiPuoi trovare approfondimenti in questi link, ma ce ne sono decisamente tanti altri.

    The Essence of the Visitor PatternThe Visitor PatternThe VISITOR Pattern as a Reusable, Generic, Type-Safe ComponentVisitor PatternVisitor Design PatternCOSC3311 Software Design Visitor PatternThe Visitor PatternVisitor pattern

    PS: Decisamente una svista che correggo subito! Grazie mille. Ciao.

    2. Dennis12 gennaio 2014 alle 12:02 PMRispondiCiao, grazie per la bellissima spiegazione di questo pattern.Ma, come hai fatto ad esempio nellesercizio 3, una classe abstract che contiene tutti i metodiabstract non sarebbe meglio dichiararla come interface?

    Giuseppe Dell'Abate31 gennaio 2014 alle 1:21 PMRispondiCiao, grazie per i complimenti e scusa per il ritardo con cui ti scrivo.Sicuramente si, in questo caso una interfaccia va benissimo.Solitamente preferisco utilizzare le classi astratti in quanto si prestano meglio in caso direfactoring, per esempio posso dichiarare dei metodi concreti disponibili a fattor comune perle classi figlie ed applicare facilmente il template pattern.Inoltre secondo un mito, forse esagerato, le classi astratte sono pi veloci delle interfacce:http://stackoverflow.com/questions/12514131/which-one-is-fast-abstract-class-or-interface.Puoi vedere altre differenze tra le due qui:

  • http://mindprod.com/jgloss/interfacevsabstract.html1. No trackbacks yet.

    Rispondi

    Concorrenza in Java: Thread, Executor e Fork/Join Simple, Double e Multi Dispatch in JavaRSS feed

    Articoli recentiInternet ed il webAlgoritmi e struttura datiJ2EE Patterns: Intercepting FilterBad Practices: Presentation, Business e Integration TiersArchitettura EsagonaleTell, dont AskConcorrenza in Java: Thread, Executor e Fork/JoinGoF Patterns: VisitorSimple, Double e Multi Dispatch in JavaGoF Patterns: Template MethodGoF Patterns: StrategyGoF Patterns: StateGoF Patterns: ObserverGoF Patterns: MementoGoF Patterns: Mediator

    Archivio mensilefebbraio 2014 (1)novembre 2013 (2)ottobre 2013 (3)giugno 2013 (1)aprile 2013 (1)novembre 2012 (1)agosto 2012 (1)luglio 2012 (1)marzo 2012 (2)

  • febbraio 2012 (1)dicembre 2011 (1)novembre 2011 (3)aprile 2011 (1)marzo 2011 (3)febbraio 2011 (3)gennaio 2011 (5)dicembre 2010 (3)novembre 2010 (6)ottobre 2010 (1)settembre 2010 (2)agosto 2010 (1)luglio 2010 (1)giugno 2010 (1)

    Post pi lettiLa tecnica della ricorsione in JavaUtilizzo dei Socket su protocolli UDP/IPGoF Patterns: DecoratorGoF Patterns: ObserverGoF Patterns: Chain of ResponsibilityGoF Patterns: StrategyGoF Patterns: StateUtilizzo dei Socket su protocolli TCP/IPConcorrenza in Java: Thread, Executor e Fork/JoinLibri

    Calendarioaprile: 2013

    L M M G V S D

    nov giu

    1 2 3 4 5 6 78 9 10 11 12 13 1415 16 17 18 19 20 2122 23 24 25 26 27 2829 30

    BlogrollClsHackinfoQjavalobbyjavaranchjavaworld

    Statistiche

  • My del.icio.usJSF 2.0 TutorialPrimeFaces - ShowCaseJVM Troubleshooting ToolsPrimeFaces Tutorial (Prime Faces for JSF 2) with EclipseEclipse IDE for Java EE Developers | PackagesLiferay Logical ArchitectureMokaByte 176 - Settembre 2012 - Java e i portaliFind Security BugsAutomated Security Testing of web applications using OWASP Zed Attack Proxy - codecentricBlogPlugins - JenkinsSecurityDistrosUnicornscan - BackTrack LinuxKali Linux Tools ListingHow to resize a VirtualBox vmdk file - Stack OverflowFritzingBionic Arduino Introduction to Microcontrollers with Arduino todbot blogApache Tomcat 6.0 (6.0.41) - Clustering/Session Replication HOW-TOTomcat 6 - ClusteringIntroduction to Selenium GridExpert Cheat Sheets & Tutorial Guides for Developers | RefcardzEnterprise Integration Patterns - Integration Patterns OverviewHome - Dr. GarbageOWASP LAPSE Project - OWASPEclipse Control Flow Graph GeneratorThe Trac ProjectMantis Bug TrackerThe wise work manager for context-based scoping | JavaWorldJava EE: Schedule jobs with WorkManagerKumar's Blog: The Work Manager API: Parallel Processing Within a J2EE ContainerGuida per risolvere il cubo di RubikGrafi: concetti fondamentali e problemi notevoli - Ricerca operativaChange UUID of Virtual Drive (VDI) in VirtualBoxCourseraScratch - Imagine, Program, ShareJava Pattern Wizard - Java Developer Tools Google DevelopersTechnical debtLehman's laws of software evolutionEnterprise Integration Patterns - Table of ContentsApps e Widget per AndroidProblema con la memoria Android? Ecco come risolverlo!Certification and Training for Software Professionals| IEEE Computer SocietyOracle Partitioning ConceptsTop 10 Java Business Rule EnginesJess, the Rule Engine for the Java Platform - Introduction to Programming with Jess in JavaJDBC RowSet ExampleStructure and Interpretation of Computer ProgramsHigh Scalability - All Time FavoritesRedmine

  • behind the times: 10 Best IDEA Inspections You're Not UsingDomande e Risposte su Java: ExecutorService: Eseguire Thread a gruppi di NStruts 2 TutorialOverview of package util.concurrent Release 1.3.4.Doug Lea's WorkstationA Java Fork-Join Calamityjeannes SCEA/OCMJEA 5 part 2&3 experiences | Down Home Country Coding With ScottSelikoff and Jeanne BoyarskyStep by step tutorial to create Keystore and Truststore file | Tech BrainwaveSun Certified Enterprise Architect (SCEA Part 2) - J2EE Test Preparation Resource - www.bm-one.comGuida a SOLARIS (per Sysadm Linux)Java Profiling: Under the Covers | JavalobbyReloading Java Classes: HotSwap and JRebel Behind the Scenes | JavalobbyDetailed Tool Descriptions - Troubleshooting Guide for Java SE 6 with HotSpot VMdynamic linkingKimera DisassemblerFree Java Books - freeprogrammingresources.comSynchronization and the Java Memory ModelThe "Double-Checked Locking is Broken" DeclarationStarting from the Singleton Design Pattern to Exploring 'The Doubleton Design Pattern' to N-ton... -CodeProjectJava e la gestione dei ThreadWhen is a Singleton not a Singleton?Lorenzo Bettini Home Page - HomePageFAQ & Guide - Create - PopulisBlog | ClsHackScript per il calcolo della chiave WPA dei router Alice Gate VoIP 2 Plus Wi-Fi | evilsocket.netAlice AGPF: lalgoritmo! White Hats CrewLinkedIn: Reading List by AmazonUniroma.TV - Gruppo Uniroma NetworkHome - Peter Lang VerlagsgruppeCome funziona - Il sito che vi spiega come funzionano le coselogo certification30 Best Websites To Download Free EBooksYouTube - Cracking SSH Logins#!/bin/the hacker's choice - THCTRANSLATOR, BINARYSCEA free study guides,notes and tipsPubblicazioni EUCIPSony PRS-900BC Reader Daily Edition PRS-900BCKIT - B&H Photoadvance java by - download the free ebook now from ePub Bud!Java IO Faster Than NIO Old is New Again! | The Buzz MediaJMX, SNMP, Java, etc...: javax.management.StandardMBean: When and Why.Class OverviewJava Graphs & Charts | AppletsChart and graph examplesjavatao.com - Java ChartsIUMSC - Indiana University Molecular Structure CenterOptimize Your Code - This blog is about optimizing software and application performance tuningPHENOELIT toolsDefault Password List How to Set SecurityManager and Java Security Policy Programmatically - Java Beans dot AsiaJava EE 5 Technologies

  • Using the Java plugin with FirefoxJSF 2.0 TutorialPrimeFaces - ShowCaseJVM Troubleshooting ToolsPrimeFaces Tutorial (Prime Faces for JSF 2) with EclipseEclipse IDE for Java EE Developers | PackagesLiferay Logical ArchitectureMokaByte 176 - Settembre 2012 - Java e i portaliFind Security BugsAutomated Security Testing of web applications using OWASP Zed Attack Proxy - codecentricBlogPlugins - JenkinsSecurityDistrosUnicornscan - BackTrack LinuxKali Linux Tools ListingHow to resize a VirtualBox vmdk file - Stack OverflowFritzingBionic Arduino Introduction to Microcontrollers with Arduino todbot blogApache Tomcat 6.0 (6.0.41) - Clustering/Session Replication HOW-TOTomcat 6 - ClusteringIntroduction to Selenium GridExpert Cheat Sheets & Tutorial Guides for Developers | RefcardzEnterprise Integration Patterns - Integration Patterns OverviewHome - Dr. GarbageOWASP LAPSE Project - OWASPEclipse Control Flow Graph GeneratorThe Trac ProjectMantis Bug TrackerThe wise work manager for context-based scoping | JavaWorldJava EE: Schedule jobs with WorkManagerKumar's Blog: The Work Manager API: Parallel Processing Within a J2EE ContainerGuida per risolvere il cubo di RubikGrafi: concetti fondamentali e problemi notevoli - Ricerca operativaChange UUID of Virtual Drive (VDI) in VirtualBoxCourseraScratch - Imagine, Program, ShareJava Pattern Wizard - Java Developer Tools Google DevelopersTechnical debtLehman's laws of software evolutionEnterprise Integration Patterns - Table of ContentsApps e Widget per AndroidProblema con la memoria Android? Ecco come risolverlo!Certification and Training for Software Professionals| IEEE Computer SocietyOracle Partitioning ConceptsTop 10 Java Business Rule EnginesJess, the Rule Engine for the Java Platform - Introduction to Programming with Jess in JavaJDBC RowSet ExampleStructure and Interpretation of Computer ProgramsHigh Scalability - All Time FavoritesRedminebehind the times: 10 Best IDEA Inspections You're Not UsingDomande e Risposte su Java: ExecutorService: Eseguire Thread a gruppi di NStruts 2 Tutorial

  • Overview of package util.concurrent Release 1.3.4.Doug Lea's WorkstationA Java Fork-Join Calamityjeannes SCEA/OCMJEA 5 part 2&3 experiences | Down Home Country Coding With ScottSelikoff and Jeanne BoyarskyStep by step tutorial to create Keystore and Truststore file | Tech BrainwaveSun Certified Enterprise Architect (SCEA Part 2) - J2EE Test Preparation Resource - www.bm-one.comGuida a SOLARIS (per Sysadm Linux)Java Profiling: Under the Covers | JavalobbyReloading Java Classes: HotSwap and JRebel Behind the Scenes | JavalobbyDetailed Tool Descriptions - Troubleshooting Guide for Java SE 6 with HotSpot VMdynamic linkingKimera DisassemblerFree Java Books - freeprogrammingresources.comSynchronization and the Java Memory ModelThe "Double-Checked Locking is Broken" DeclarationStarting from the Singleton Design Pattern to Exploring 'The Doubleton Design Pattern' to N-ton... -CodeProjectJava e la gestione dei ThreadWhen is a Singleton not a Singleton?Lorenzo Bettini Home Page - HomePageFAQ & Guide - Create - PopulisBlog | ClsHackScript per il calcolo della chiave WPA dei router Alice Gate VoIP 2 Plus Wi-Fi | evilsocket.netAlice AGPF: lalgoritmo! White Hats CrewLinkedIn: Reading List by AmazonUniroma.TV - Gruppo Uniroma NetworkHome - Peter Lang VerlagsgruppeCome funziona - Il sito che vi spiega come funzionano le coselogo certification30 Best Websites To Download Free EBooksYouTube - Cracking SSH Logins#!/bin/the hacker's choice - THCTRANSLATOR, BINARYSCEA free study guides,notes and tipsPubblicazioni EUCIPSony PRS-900BC Reader Daily Edition PRS-900BCKIT - B&H Photoadvance java by - download the free ebook now from ePub Bud!Java IO Faster Than NIO Old is New Again! | The Buzz MediaJMX, SNMP, Java, etc...: javax.management.StandardMBean: When and Why.Class OverviewJava Graphs & Charts | AppletsChart and graph examplesjavatao.com - Java ChartsIUMSC - Indiana University Molecular Structure CenterOptimize Your Code - This blog is about optimizing software and application performance tuningPHENOELIT toolsDefault Password List How to Set SecurityManager and Java Security Policy Programmatically - Java Beans dot AsiaJava EE 5 TechnologiesUsing the Java plugin with Firefox

    Alto

  • Blog su WordPress.com. The INove Theme.