Visitor Design Pattern
Summary
Visitor Design pattern follows the open/closed principle and allows us to add new operations to be added to object structure. Open/Closed principle states that entities should be able to extend its behavior or add need new functionality without changing its own implementation.
Important Points
Visitor Design Pattern uses Double Dispatch to invoke a method at run time based on the object on which method is defined and its parameter.Visitor represents operations or functionality to be performed on different nodes of an object structure.
Visitor Pattern follows Open/Closed Principle.
Useful in adding new behavior or functionality to a object tree, without modifying the original Objects code.
Advantage
We can add new functionality to the Hierarchy of Classes without changing the classes.Disadvantage
The arguments visiting methods have to be known in advance.Details
The participants classes in this pattern are:
Visitor (visit)-- This is an interface or an abstract class used to declare the visit operations for all the types of visitable classes.
ConcreteVisitor -- For each type of visitor all the visit methods, declared in abstract visitor, must be implemented. Each Visitor will be responsible for different operations.
Visitable (accept)-- is an interface which declares the accept operation. This is the entry point which enables an object to be “visited” by the visitor object.
ConcreteVisitable -- Those classes implements the Visitable interface or class and defines the accept operation.
Simple Use Case
This example is about Bookmarks in Browsers. Lets assume we want to process all the bookmarks stored in all browsers and process them.
We will consider that we can have many book marks in a Browser, similarly we can have different Browsers like Firefox, Chrome, IE etc in our workstation or laptop.
Our Model Classes will represent Workstation, Browsers and Bookmarks etc.
Let's say at some point we want to grab all the bookmarks in a Workstation across all different browsers and print them.
We can declare a Visitor (Say PrintAllBookmarks etc) and propagate through the Object chain to print them.
We can also create a different Visitor( say Remove bookmark) which will go though the Object structure and remove bookmarks as per some condition.
We will consider that we can have many book marks in a Browser, similarly we can have different Browsers like Firefox, Chrome, IE etc in our workstation or laptop.
Our Model Classes will represent Workstation, Browsers and Bookmarks etc.
Let's say at some point we want to grab all the bookmarks in a Workstation across all different browsers and print them.
We can declare a Visitor (Say PrintAllBookmarks etc) and propagate through the Object chain to print them.
We can also create a different Visitor( say Remove bookmark) which will go though the Object structure and remove bookmarks as per some condition.
Class Diagram
Sample Code
/** Visitor Interface **/
public interface Visitor {
void visit(WorkStation workstation);
}
/**
* This Class represent a Workstation Object.
* Workstation can have different Browsers installed on it.
*
*/
public class WorkStation {
private String name;
List browsers = new ArrayList();
public void accept(Visitor visitor) {
visitor.visit(this);
}
//GETTERS and SETTERS.....
public String getWorkstationName() {
return name;
}
public void setWorkstationName(String workstationName) {
this.name = workstationName;
}
public List getBrowsers() {
return browsers;
}
public void addBrowser(Browser browser) {
this.browsers.add(browser);
}
}
/**
* Represents a Browser Object.
*
*/
public class Browser {
private String name;
List bookmarks = new ArrayList ();
public Browser(String name){
this.name = name;
}
//GETTERS and SETTERS.....
public String getBrowserName() {
return name;
}
public List getBookmarks() {
return bookmarks;
}
public void addBookmark(String bookmark) {
this.bookmarks.add(bookmark);
}
}
/**
* Concrete visitor implementation. It visits workstation object to read all
* Browsers and bookmarks and returns them.
*
*/
public class PrintNodeValueVisitor implements Visitor {
StringBuilder nodeValue = new StringBuilder();
@Override
public void visit(WorkStation workstation) {
StringBuilder str = new StringBuilder();
str.append("{")
.append("WorkStationName:").append(workstation.getWorkstationName())
.append("{");
str.append("Browsers [");
for(Browser browser: workstation.getBrowsers()){
str.append("BrowserName:").append(browser.getBrowserName());
str.append("BookMarkDetails [");
for(NameValuePair bookmark : browser.getBookmarks()){
str.append("BookMarkName:");
str. append(bookmark.name);
str. append(",");
str.append("BookMarkURL:");
str.append(bookmark.value);
}
str.append("]");
}
str.append("]");
str.append("}");
str.append("}");
nodeValue = str;
}
}
Full source code can be found on github here
https://github.com/siddharthagit/Sidd_javaprojDP/tree/master/src/dp/behavioral/visitor
Comments
Post a Comment