Svoju primenu VisitorDP nalazi kao rešenje problema koji se često javlja u OO sistemima, a koji se odnosi na programiranje mehanizma koji će za zadatu hijerarhiju klasa i rekurzivnu strukturu podataku (koja sadrži elemente ove hijerarhije) omogućiti prolazak kroz sve elemente rekurzivne strukture podataka i nad pojedinim elementima izvršiti operacije specifične za taj element.
Kompajler vrši uobičajeno transformaciju programa u neku internu strukturu podataka.(najčešće sintaksno stablo).
Kreiranje sintaksnog stabla je tek početak prevođenja programa.
Svi ovi problemi imaju jednu zajedničku crtu: kompajler prolazi kroz sve delove stabla i uradi nešto nad njima.
Ideja1 (intuitivni prilaz problemu ): Neka je Cvor osnovna klasa koja reprezentuje čvor sintaksnog stabla. Ideja je deklarisati metod u klasi Cvor , koji obavlja željenu operaciju na čvoru u stablu, a onda u svim podklasama se može redefinisati ovaj metod da obavi operaciju koja odgovara konkretnom čvoru.
Mane ideje 1:
Mehanizam ideje 2:
Kreirati apstraktnu klasu koja definiše generalni izgled "posetioca".
public abstract class Visitor{
public void Obrada(Cvor c);
public void Obrada(Izraz i);
. . .
}
I , naravno, svakoj klasi u hijerarhiji dodati metod koji omogućava "posetiocu" da "poseti" dati element i prosledi mu sve potrebne informacije:
public void Visit(Visitor v) {
v.Obrada(this); }
Na primer, ako se želi odštampati sintaksno stablo i ako promenljiva root sadrži koren stabla onda se preduzima:
Visitor v = new Stampati();
root.Visit(v);
gde implementacija "posetioca" za štampanje sintaksnog stabla:
public class Stampati extends Visitor {
public void Obrada(Izraz i) {
i.expr.Visit(this);
System.out.println(";"); }
public void Obrada(AditivniIzraz i) {
System.out.print("(");
i.left.Visit(this);
System.out.print(" + ");
i.right.Visit(this);
System.out.print(")"); }
...
}
Visitor DP nije naročito pogodan u situacijama kada se hijerarhija klasa koje čine elemente strukture podataka često menja u toku razvoja programa.
Npr. kada bi morala da se doda neka klasa u Cvor hijerarhiji, npr.BitwiseIzraz, tada bi bilo nužno promeniti svaku klasu u Visitor hijerarhiji i definisati metod Obrada(BitwiseIzraz i) u svakoj od tih klasa.
Mark Linton je osmislio ime "visitor" u specifikaciji "Fresco Application Toolkit" (kompanija X Consortium) iz januara 1993.
Jslint je alatka koja statistički skanira Java kod ne bi li našla mesta osetljiva po pitanju sigurnosti. Sami autori su predložili da pošto Jslint parsira source datoteku u sintaksno drvo, onda ono može da se obilazi koriščenjem Visitor design pattern-a. Ovaj pattern enkapsulira svaku operaciju nad sintaksnim drvetom u jedan objekat nazvan Visitor, dozvoljavajući korisnicima da definišu nove operacije nad drvetom bez izmene elemenata drveta. Na taj način se enkodira svaka (sigurnosna) rupa u jedan Visitor koji obilazi drvo raščlanjivanja tragajuci za instancama koje su sporne.
Sama alatka Jslint može da se modifikuje da skanira kod na drugim jezicima putem ova tri koraka:
Jedna od primena Visitor DP-a je u okviru grep usluga nekih softverskih proizvoda, koji u fajlu pretražuju zadati string.
Visitor DP (sa metodima accept() i visitConcreteElement() ) je još jedan od mehanizama koji omogućuju eliminaciju naredbi višestrukog granjanja.
Klasa visitor-a se sreće i kod Smalltalk-80 pod imenom ProgramNodeEnumerator koja se upotrebljava za algoritme koji vrše ispitivanja izvornog koda.
Interpretator DP
Visitor DP se može iskoristiti radi obavljanja interpretacije.
Composite DP
U sistemu koji koristi Composite DP može da se upotrebi
Visitor DP da bi se obavile operacije nad pojedinačnim komponentama.
← Singleton DP | Uvod | Iterator DP → |