Visitor Design Pattern in PHP
In the Visitor pattern, one class calls a function in another class with the current instance of itself. The called class has special functions for each class that can call it.
In this example, the BookVisitee
can call the visitBook
function in any function extending the Visitor
class. By doing this new Visitors which format the BookVisitee
information can easily be added without changing the BookVisitee
at all.
<?php
abstract class Visitee {
abstract function accept(Visitor $visitorIn);
}
class BookVisitee extends Visitee {
private $author;
private $title;
function __construct($title_in, $author_in) {
$this->author = $author_in;
$this->title = $title_in;
}
function getAuthor() {return $this->author;}
function getTitle() {return $this->title;}
function accept(Visitor $visitorIn) {
$visitorIn->visitBook($this);
}
}
class SoftwareVisitee extends Visitee {
private $title;
private $softwareCompany;
private $softwareCompanyURL;
function __construct($title_in, $softwareCompany_in, $softwareCompanyURL_in) {
$this->title = $title_in;
$this->softwareCompany = $softwareCompany_in;
$this->softwareCompanyURL = $softwareCompanyURL_in;
}
function getSoftwareCompany() {return $this->softwareCompany;}
function getSoftwareCompanyURL() {return $this->softwareCompanyURL;}
function getTitle() {return $this->title;}
function accept(Visitor $visitorIn) {
$visitorIn->visitSoftware($this);
}
}
abstract class Visitor {
abstract function visitBook(BookVisitee $bookVisitee_In);
abstract function visitSoftware(SoftwareVisitee $softwareVisitee_In);
}
class PlainDescriptionVisitor extends Visitor {
private $description = NULL;
function getDescription() {
return $this->description;
}
function setDescription($descriptionIn) {
$this->description = $descriptionIn;
}
function visitBook(BookVisitee $bookVisiteeIn) {
$this->setDescription($bookVisiteeIn->getTitle().'. written by '.$bookVisiteeIn->getAuthor());
}
function visitSoftware(SoftwareVisitee $softwareVisiteeIn) {
$this->setDescription($softwareVisiteeIn->getTitle().
'. made by '.$softwareVisiteeIn->getSoftwareCompany().
'. website at '.$softwareVisiteeIn->getSoftwareCompanyURL());
}
}
class FancyDescriptionVisitor extends Visitor {
private $description = NULL;
function getDescription() { return $this->description; }
function setDescription($descriptionIn) {
$this->description = $descriptionIn;
}
function visitBook(BookVisitee $bookVisiteeIn) {
$this->setDescription($bookVisiteeIn->getTitle().
'...!*@*! written !*! by !@! '.$bookVisiteeIn->getAuthor());
}
function visitSoftware(SoftwareVisitee $softwareVisiteeIn) {
$this->setDescription($softwareVisiteeIn->getTitle().
'...!!! made !*! by !@@! '.$softwareVisiteeIn->getSoftwareCompany().
'...www website !**! at http://'.$softwareVisiteeIn->getSoftwareCompanyURL());
}
}
writeln('BEGIN TESTING VISITOR PATTERN');
writeln('');
$book = new BookVisitee('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides');
$software = new SoftwareVisitee('Zend Studio', 'Zend Technologies', 'www.zend.com');
$plainVisitor = new PlainDescriptionVisitor();
acceptVisitor($book,$plainVisitor);
writeln('plain description of book: '.$plainVisitor->getDescription());
acceptVisitor($software,$plainVisitor);
writeln('plain description of software: '.$plainVisitor->getDescription());
writeln('');
$fancyVisitor = new FancyDescriptionVisitor();
acceptVisitor($book,$fancyVisitor);
writeln('fancy description of book: '.$fancyVisitor->getDescription());
acceptVisitor($software,$fancyVisitor);
writeln('fancy description of software: '.$fancyVisitor->getDescription());
writeln('END TESTING VISITOR PATTERN');
//double dispatch any visitor and visitee objects
function acceptVisitor(Visitee $visitee_in, Visitor $visitor_in) {
$visitee_in->accept($visitor_in);
}
function writeln($line_in) {
echo $line_in."<br/>";
}
?>
Output
BEGIN TESTING VISITOR PATTERN plain description of book: Design Patterns . written by Gamma, Helm, Johnson, and Vlissides plain description of software: Zend Studio . made by Zend Technologies . website at www.zend.com fancy description of book: Design Patterns ...!*@*! written !*! by !@! Gamma, Helm, Johnson, and Vlissides fancy description of software: Zend Studio ...!!! made !*! by !@@! Zend Technologies ...www website !**! at http://www.zend.com END TESTING VISITOR PATTERN