Archive for the 'Visitor' Category

PHP Visitor Design Pattern III: Traverser

phper250After going through single and double dispatch, it’s time to shift gears to the next major feature of the Visitor pattern; the Traverser. One of the most important (and often omitted) components of the Visitor design pattern is the Object Structure. In Part II the focus is on the double-dispatch, the number of elements that could be visited at once. The Object Structure is set up to collect the allowable visitors to visit the elements; however, only one element at at time can be displayed because the middle of the the foreach loop in the confirm() method contains a return statement—so as soon a the iteration begins, it ends with the return statement. (Let’s face it; it’s a pseudo-transveral.) Since Part II focuses on the double-dispatch, the number of elements that could be visited at one time is a tangental issue. This post, though, focuses squarely on the traversal process and the multiple elements that can be visited in a single process.

Updating the Visitor

In order to have all of the parts merrily humming along, a few changes are in order. Importantly, once these changes are made, all of the parts are still working and interacting together. To see what’s changed but how the structure is basically the same as the visitor in Part II focuses on the double-dispatch, the number of elements that could be visited at on, download the new set of files and test the new multiple element visitor:
PlayDownload
Right away, you will see that instead of radio buttons, the HTML5 UI uses check boxes for selecting one, two or three elements and then applies the visitors one at a time.(You can supply your own error-handling routine for selecting no elements!)

The HTML Element Array

One of the nicest attributes in HTML is the ability to treat a group of checkboxes with “element values” (elements as elements in an array). Each checkbox is given a name with empty brackets (e.g., my element[]). All of the selected (checked) checkboxes with the identical element name are automatically included in an array with the element name. You don’t have to worry about the unchecked ones as they are not included in the array passed to PHP.

< !DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="visitor.css"/>
    <title>The Traverser</title>
</head>
<body>
    <h3>Traverser: Multiple Elements & Visitor Color</h3>
    <div id="choose">
        <div id="geom">
    <form action="Client.php" method = "post" target = "feedback">
        <input type="checkbox" name="shape[]" value="Circle" checked="True"/>&nbsp;Dispatch a circle<br />
        <input type="checkbox" name="shape[]" value="Square"/>&nbsp;Dispatch a square<br />
        <input type="checkbox" name="shape[]" value="Triangle"/>&nbsp;Dispatch a triangle<br />
        </form></div>
 
        <aside>
            <fieldset>
                <legend>Color Visitor</legend>
        <input type="radio" name="color" value="GreenVisitor" checked="True"/>&nbsp;Green<br />
        <input type="radio" name="color" value="RedVisitor"/>&nbsp;Red<br />
        <input type="radio" name="color" value="BlueVisitor"/>&nbsp;Blue<br />
        <input type="radio" name="color" value="BurntOrangeVisitor"/>&nbsp;Burnt Orange<br />
        </fieldset>
        </aside>
        </div>
        <p><input type="submit" name="sender" value="Double Dispatch"/></p>
 
    <div>
    <iframe name="feedback" width="680" height="680">feedback</iframe>
    </div>
</body>
</html>

That checkbox array feature made it very easy to pass the shape class names (as strings) to the Client.

The Updated Client

The Client class is changed slightly to accept an array of shapes rather than just one as was done in Parts I and II of the Visitor series. Likewise, some steps were tightened up in the ObjectStructure class for cleaning up the traversal process.

< ?php
//Client.php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
// Autoload given function name.
function includeAll($className)
{
    include_once($className . '.php');
}
//Register
spl_autoload_register('includeAll');
 
class Client
{
    private static $shapeElement;
    private static $color;
    private static $package;
 
    //client request
    public static function request()
    {
      self::$shapeElement= array();
      self::$shapeElement=$_POST['shape'];
      self::$color=$_POST['color'];
      self::$package= array();
 
      $obStructure = new ObjectStructure();
      $colorVisitor= new self::$color();
 
      //Attach concrete elements to array & accept visitor
      foreach (self::$shapeElement as $shapeNow)
      {
        $obStructure->attach(new $shapeNow,$colorVisitor);
      }
 
      //Display selected shapes
      self::$package=$obStructure->getElements();
      foreach (self::$package as $colorShape)
      {
        echo $colorShape->showShape();
      }
    } 
}
Client::request();
?>

The Client calls on the traversal process using an instance of the OjbectStructure. The attach() method now has two parameters; a shape and a color. The shape is passed as a shape element generated by the foreach loop, creating a new shape with each iteration while adding the same color visitor to all shapes. Once everything has been stored in the ObjectStructure, a second loop calls the getElements() methods, which returns shapes with the appropriate color visitor.

The ObjectStructure

The ObjectStructure class is small but mighty. The Gang of Four note,

A client that uses the Visitor pattern must create a ConcreteVisitor object and then traverse the object structure, visiting each element with the visitor.

Several choices are available to transverse the elements from the client through the object structure, but as seen, the humble (yet mighty) foreach loop handles the job elegantly and efficiently. The OjbectStructure provides the methods the client uses for traversal.

< ?php
//ObjectStructure.php
class ObjectStructure
{
    private $elements=array();
 
    public function attach(IElement $element,IVisitor $colorVis)
    {
        $element->accept($colorVis);
        array_push($this->elements,$element);
    }
 
    public function getElements()
    {
        return $this->elements;
    }  
}
?>

In Part II of the Visitor series, the attach() method only served to push the element onto an array, but here the method, now with two instead of one parameter serves double duty. First, each shape accepts (using the IElement::accept() method) the visitor. Second, each shape is added to an array, $elements. In some respects, this acts like a setter operation.

The only other method, getElements() returns the shapes with the accepted color. The client can then display them on the screen.
Continue reading ‘PHP Visitor Design Pattern III: Traverser’

Share

PHP Visitor Design Pattern II: The Double Dispatch

visitor2x

The Visitor pattern uses a double dispatch even with languages that are inherently single dispatch (such as PHP). In this second installment of the Visitor, I’d like to look at the concept and utility of double dispatch and role of the ObjectStructure in creating a working Visitor example that can be transformed into a practical application.

In Part I PHP Visitor Design Pattern I: The Single Dispatch, the focus was on using a single dispatch and a “pretend visitor.” This post shows how to create a visitor object based on both a Visitor interface and ConcreteVisitor implementations that are used in concert with the Element participants via the ObjectStructure. In order to do this, a couple more concrete Elements have been added to the example begun in Part I of the Visitor.

The Visitor Design Pattern Diagram

The Part I Visitor post suggests that the Visitor class diagram is a bit daunting, and so I held off until now to show it. If you look at the bottom portion of Figure 1, you will see that the example in Part I handled all of the Element participants, and included a “pretend visitor” where the Accept(Visitor) implementation in an actual Visitor pattern goes. So, you have some idea of what close to half of the Visitor does.

Figure 1: Visitor Class Diagram

Figure 1: Visitor Class Diagram

You can get a hint at what double-dispatch is by looking at the dual connections that the Client has to both the Visitor and Element (via the ObjectStructure). In the pattern, the Client is implied, but it’s clear to see the double reference to both the Visitor and the ObjectStructure which holds a reference to the Element.

This particular implementation of the Visitor pattern extends the example used in Part I where a “pretend” visitor is an operation that provides the fill color of SVG images. In this implementation, the fill color operation is provided by an actual visitor object. A third and forth Element class have been added, one with a visitor (Triangle) and one that does not have a visitor (zigzag lines have no fill colors—just a stroke color.) Figure 2 shows the program as a file diagram:

Figure 2: File diagram of Visitor pattern in PHP

Figure 2: File diagram of Visitor pattern in PHP

To get an idea of what the application does and look at the overall code, run the program and download the files:
PlayDownload

When you run the program, you can see that the shape (concrete Element) and the color (concrete Visitor) are selected separately. Those separate selections are to highlight the concept of double-dispatch. A shape and color are selected with the understanding that the developer had not included a fill color originally, and instead of starting from scratch to re-program the shape selector, the developer added a visitor. To see how double-dispatch works in a Visitor pattern, follow the path from the Client to the ObjectStructure and to the IElement::accept() method.

Double-Dispatch and Traversing Elements with Visitors

Figure 3: ObjectStructure and IElement::accept() double-dispatch link

Figure 3: ObjectStructure and IElement::accept() double-dispatch link

One of the key participants in the Visitor pattern is the ObjectStructure class. The Gang of Four introduce the ObjectStructure participant to handle traversing the Element objects that may need the attention of a Visitor. The pattern solves the double-dispatch problem by including a concrete visitor in the Element::accept(IVisitor) method. However, the path from Client-request to double-dispatch first goes through the ObjectStructure class. By looking the Client, ObjectStructure and a concrete Element, you can see the double-dispatch process:

< ?php
/*
* CLIENT
*/
//Client.php
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
//Autoload code
function includeAll($className)
{
    include_once($className . '.php');
}
spl_autoload_register('includeAll');
 
//Begin Client class
class Client
{
    private static $shapeElement;
    private static $color;
    //client request
    public static function request()
    {
      self::$shapeElement=$_POST['shape'];
      self::$color=$_POST['color'];
 
      $obStructure = new ObjectStructure();
      $obStructure->attach(new self::$shapeElement());
      $colorVisitor= new self::$color();
      echo $obStructure->confirm($colorVisitor);
    } 
}
Client::request();
?>
 
 
< ?php
/*
* OBJECT STRUCTURE
*/
//ObjectStructure.php
class ObjectStructure
{
    private $elements=array();
 
    public function attach(IElement $element)
    {
         array_push($this->elements,$element);
    }
 
    public function confirm(IVisitor $visitor)
    {
         foreach($this->elements as $elementNow)
         {
              return $elementNow->accept($visitor);
         }
    }
}
?>
 
 
< ?php
/*
* ELEMENT
*/
//Circle.php
class Circle implements IElement
{
    private $visColor;
 
    public function accept(IVisitor $visitor)
    {
        $visitor->visitCircle($this);
        return $this->showShape();
    }
 
    private function showShape()
    {
        $circleShape= IElement::SVG . "<circle cx='110' cy='110' r='100' fill='{$this->doColor()}' stroke='blue' stroke-width='1' />";
        return $circleShape;
    }
 
    public function setColor($visitorColor)
    {
         $this->visColor = $visitorColor;
    }
 
    private function doColor()
    {
        return $this-> visColor;
    }
}
?>
 
</circle>

Stepping through the process, the Client first (1) instantiates an instance of ObjectStructure. Second (2) the Client uses the ObjectStructure::attach() method to push the selected element instance onto an array. Third (3) the Client passes the selected visitor to the ObjectStructure::confirm() method, which in turn, fourth (4) calls the Element::accept($v) method which passes the concrete visitor to all of the elements in the array. Since this example is very simple, it only includes one element and one visitor at a time, and so the array will only contain a single element. However, because of the ObjectStructure class, you can add more elements if needed. (The following sections show more detail on how double-dispatch works and how the visitors are implemented.)
Continue reading ‘PHP Visitor Design Pattern II: The Double Dispatch’

Share

PHP Visitor Design Pattern I: The Single Dispatch

visitorTime to Add an Operation

I’ve always liked the Visitor Pattern, but it can appear somewhat daunting from the looks of the pattern’s class diagram. However, by easing into it, it’s fairly manageable and quite useful. In a nutshell, the Visitor allows developers to create programs that perform operations on elements in an object structure without changing the classes subject to the operation. In some respects this sounds a lot like the Decorator pattern but instead of adding properties, the Visitor pattern “visits” the structure with required operations.

Where the visitor comes into play is when you have a set of objects that share a common interface, but some–just some–need a method that does something not part of the interface, but it should not disrupt the interface or the related objects that do not need the method’s operation. In situations where added requirements crop up for extant structures, the Visitor is a welcomed guest.

An Element and a Pretend Visitor

To get started, instead of looking at the class diagram for the whole pattern, I want to take the Element interface and two concrete implementations of that interface as a point of departure. This particular set of concrete Element implementations create shapes using SVG graphics. One implementation creates a circle and the other a a square. Click the Play button to see what the program does and the Download button to view the files:
PlayDownload

A visitor object is one that adds an operation to an existing object without changing the object in the context of its interface. This first implementation assumes that the developer just wanted to make shapes and did not want to add fill color; so the fill color attribute of the SVG element has been left blank. (If no value is entered in the color attribute, it defaults to black–more on that later.)

In order to to show how a blank color is filled, the two shape-making implementations (Circle and Square) have a “pretend visitor.” The “visitor” is nothing but a private method that adds color. It is instructive insofar as it illustrates how to create an operation to add color to an existing method within a class.

First, take a look at the Element interface (IElement). It contains a constant with an immutable state and two methods; one for returning an object and the other the “pretend” visitor” supplies color to an otherwise colorless shape.

 
interface IElement
{
    //Constant for mutually shared code
    const SVG ="<svg width='2.2cm' height='2.2cm' viewBox='0 0 220 220'>";
    //Return object
    function showShape();
 
    //Pretend visitor
    function doColor();
}
?>
</svg>

Next, two implementations of the IElement create Square and Circle classes. Importing the SVG element from the IElement interface (stored as a constant), each class simply returns the code for the requested shape.

//Square.php
< ?php
class Square implements IElement
{
    public function showShape()
    {
        $squareShape= IElement::SVG . "<rect x='1' y='1' width='200' height='200' fill='{$this->doColor()}' stroke='blue' stroke-width='1' />";
        return $squareShape;
    }
 
    //Pretend visitor
    function doColor()
    {
        //pretent visitor red
        return "#b00";
    }
}
?>
 
//Circle.php
< ?php
class Circle implements IElement
{
    public function showShape()
    {
        $circleShape= IElement::SVG . "<circle cx='110' cy='110' r='100' fill='{$this->doColor()}' stroke='blue' stroke-width='1' />";
        return $circleShape;
    }
 
    //Pretend visitor
    function doColor()
    {
        //pretent visitor green
        return "#0b0";
    }
}
?>

The pretend visitor is the doColor() method. It acts like a coloring operation that is coming from “somewhere else.” Subsequent posts examine how a real visitor works, but for now, just take a look at how an outside operation is used to establish color in the showShape() method. (Continue to learn about the roles of the Client and Single-Dispatch.) Continue reading ‘PHP Visitor Design Pattern I: The Single Dispatch’

Share