Plug-in Pattern in PHP and JavaScript

In this second part of the series, I demonstrated how to use the “Plug-in” pattern for developing a fully-pluggable application that renders different types of elements on screen. The “plug-ins” passed to the client renderer will be objects that generate basic HTML/JavaScript code and nothing else.

Although the term is like a wild card used in fields other than software engineering, “Plug-in” is also the name of a design pattern which permits you to extend the functionality of a system (an application, a library, or a full-blown MVC framework) by means of a clever use of Composition and generic interfaces. These can be native, or in the form of abstract classes.

Like any other pattern, “Plug-in” is language-agnostic. This implies that it can be implemented in any programming language, including PHP. In keeping with this concept, in the introductory part of this series I went through the development of a rather primitive PHP application. Its main area of responsibility was to display, through a single client rendering class, different types of HTML objects, such as divs and paragraphs.

Thanks to the use of the “Plug-in” pattern, though, injecting each object into the internals of the pertinent client class and then rendering it on screen was as simple as replacing one Lego block with another. Not too bad, huh?

To fully honor the pattern’s name, however, the aforementioned application should be capable of rendering any type of object, not just the couple of HTML widgets referenced before. Well, to demonstrate this concept from a practical standpoint, in this second chapter of the series I’m going to define a brand new class, which will be tasked with rendering simple JavaScript alert boxes.

If you ask me what’s so special about this class, I have to say… nothing, except for a subtle detail worth noting: due the flexibility of the “Plug-in” pattern, the class will be passed to the client renderer and displayed on the browser without having to alter a single portion of the source classes developed so far.

So, do you want to see how this entirely new class will be built and “plugged in” to the existing infrastructure of this sample rendering application? Then don’t hesitate anymore; begin reading!

Review: a basic implementation of the “Plug-in” pattern

Before I show you the definition of the alert box class mentioned in the introduction, and how it will be afterward plugged in to the corresponding client rendering class, it’d be useful to review the example developed in the previous part of the series, It basically demonstrated the functionality of the “Plug-in” pattern when used with two different HTML objects.

Having said that, here’s the common interface implemented by the originating classes of these objects:

(Render/Renderable.php)

<?php

namespace Render;

interface Renderable
{
    public function render(); 
}

Since the “Renderable()” interface only declares a single “render()” method, look at the following classes. The first one is an abstract parent that defines the structure and behavior of generic HTML elements, while the other two are implementers of the interface, charged with rendering divs and paragraphs respectively:

(Html/AbstractHtmlElement.php)

<?php

namespace Html;

abstract class AbstractHtmlElement
{
    protected $_content;
    protected $_id;
    protected $_class;
   
    /**
     * Constructor
     */
    public function __construct($content, $id = ”, $class = ”)
    {
        if (is_string($content)) {
           $this->_content = $content;
        }
        if (is_string($id) && !empty($id)) {
            $this->_id = $id;
        }
        if (is_string($class) && !empty($class)) {
            $this->_class = $class;
        }   
    }   
}

 

(Html/Div.php)

<?php

namespace Html;
use Render;

class Div extends AbstractHtmlElement implements RenderRenderable
{
    /**
     * Render the Div element
     */
    public function render()
    {
        $html = ‘<div’;
        if ($this->_id) {
            $html .= ‘ id="’ . $this->_id . ‘"’;
        }
        if ($this->_class) {
           $html .= ‘ class="’ . $this->_class . ‘"’;
        }
        $html .= ‘>’ . $this->_content . ‘</div>’ . "n";
        return $html;
    }
}

 

(Html/Paragraph.php)

<?php

namespace Html;
use Render;

class Paragraph extends AbstractHtmlElement implements RenderRenderable
{
    /**
     * Render the Paragraph element
     */
    public function render()
    {
        $html = ‘<p’;
        if ($this->_id) {
            $html .= ‘ id="’ . $this->_id . ‘"’;
        }
        if ($this->_class) {
           $html .= ‘ class="’ . $this->_class . ‘"’;
        }
        $html .= ‘>’ . $this->_content . ‘</p>’ . "n";
        return $html;
    }
}

By now you’ve grasped the logic driving the earlier HTML classes, so I suggest you pay attention to the implementation of the following one. It is a composite capable of displaying on screen any “renderable” object previously added through its “addElement()” method.

The client class looks like this:

(Render/Renderer.php)

<?php

namespace Render;

class Renderer
{
    protected $_elements = array();
   
    /**
     * Add a single renderable element
     */
    public function addElement(Renderable $element)
    {
        $this->_elements[] = $element;
        return $this;
    }
   
    /**
     * Remove a renderable element
     */
    public function removeElement(Renderable $element)
    {
        if (in_array($element, $this->_elements, true)) {
            $elements = array();
            foreach ($this->_elements as $_element) {
                if ($element !== $_element) {
                    $elements[] = $_element;
                }
            }
            $this->_elements = $elements;
        }
    }
   
    /**
     * Add multiple renderable elements
     */
    public function addElements(array $elements)
    {
        if (!empty($elements)) {
            foreach ($elements as $element) {
                $this->addElement($element);
            }
        }
    }
   
    /**
     * Render all the inputted renderable elements
     */
    public function render()
    {
        $output = ”;
        if (!empty($this->_elements)) {
            foreach ($this->_elements as $_element) {
                $output .= $_element->render();
            }
        }
        return $output;
    }    
}

While at first glance it seems that the above “Renderer” class does nothing particularly interesting, except render some inputted elements, this is a misconception, trust me. Even at a basic level, this class gets the pieces required by the “Plug-in” pattern working together. On the one hand, it uses Composition to inject the elements in question, while on the other hand it takes advantage of an interface (a simple contract, in this case) to make sure that those elements are really “renderable.”

If this concept sounds somewhat confusing to you, take a look at the following code snippet, which shows how to display on the browser the markup corresponding to the “Div” and “Paragraph” class just defined:    

<?php

use HtmlDiv as Div,
    HtmlParagraph as Paragraph,
    RenderRenderer as Renderer;
   
// include the autoloader
require_once ‘Autoloader.php’;
Autoloader::getInstance();

// create some HTML elements
$div = new Div(‘This is the sample content for the div element.’, ‘one_id’, ‘one_class’);
$par = new Paragraph(‘This is the sample content for the paragraph element.’, ‘another_id’, ‘another_class’);

// create the renderer and add the previous elements to it
$renderer = new Renderer;
echo $renderer->addElement($div)
              ->addElement($par)
              ->render();

/* displays the following

<div id="one_id" class="one_class">This is the sample content for the div element.</div>
<p id="another_id" class="another_class">This is the sample content for the paragraph element.</p>

*/

For the sake of brevity, in this case I omitted the definition of the autoloader, as this was covered in detail in the previous part of the series. This shouldn’t be an obstacle, though, to understanding how the previous script works. All that it does is input a div and a paragraph object into the client renderer class and display the resulting HTML on screen.

Beyond the simplicity of this example, the beauty of it is that the client renderer accepts any type of object, as long as it’s an implementer of the “Renderable” interface. But what does this buy us? Well, if I ever wanted to write a separate class that renders a type of content that isn’t HTML and plug it into the renderer, the process would be dead simple.

Considering that the best way to demonstrate the “pluggability” of this sample application is by adding  such a class to it, in the next section I’m going to create a new class. It will be charged with rendering basic JavaScript alert boxes. Best of all, injecting an instance of this class into the previous renderer won’t require us to modify or refactor any section of its existing source code.

Now, to see how this JavaScript class will be created, click on the link below and keep reading.

{mospagebreak title=Building a class to display JavaScript alert boxes}

If you’re still not sure about the flexibility of the previous rendering application, then when I show you how easy it is to add a new “plug-in” to it, all of your doubts should vanish. As I said in the preceding section, the “plug-in” that I plan to implement in this case is a basic class that renders some JavaScript alert boxes. Its source code is shown below:  

(Javascript/AlertBox.php)

<?php

namespace Javascript;
use Render;

class AlertBox implements RenderRenderable
{
    protected $_content;
   
    /**
     * Constructor
     */
    public function __construct($content)
    {
        if (is_string($content) && !empty($content)) {
            $this->_content = $content;
        }
    }
   
    /**
     * Render the alert box
     */
    public function render()
    {
        return ‘<script>alert("’ . $this->_content . ‘");</script>’ . "n";
    }   
}

Admittedly, the definition of the above “AlertBox” class is so easy to follow that it doesn’t bear any further explanation. However, there’s a tiny detail worth stressing, in case you haven’t spotted it yet. The class is effectively an implementer of the already familiar “Renderable” interface, so in theory an instance of it could be passed to the previous client rendering class and displayed appropriately.

While this sounds simple to achieve, the best way to check if it actually works is to create a whole new example that injects an alert box object into the internals of the client renderer.

This example will be created in the following segment, so move on and read the next few lines.  

Putting the “AlertBox” class to work

As I said in the preceding section, below I included a script that shows how to render on screen the alert box just created, together with the two HTML widgets previously defined. Check it out:

<?php

use HtmlDiv as Div,
    HtmlParagraph as Paragraph,
    JavaScriptAlertBox as AlertBox,
    RenderRenderer as Renderer;
   
// include the autoloader
require_once ‘Autoloader.php’;
Autoloader::getInstance();

// create some HTML elements
$div = new Div(‘This is the sample content for the div element.’, ‘one_id’, ‘one_class’);
$par = new Paragraph(‘This is the sample content for the paragraph element.’, ‘another_id’, ‘another_class’);

// create an alert box
$alert = new AlertBox(‘This is the sample content for the alert box.’);

// create the renderer and add the previous elements to it
$renderer = new Renderer;
echo $renderer->addElement($div)
              ->addElement($par)
              ->addElement($alert)
              ->render();

As you can see above, the script first spawns a pair of HTML objects along with an alert box, which are then added to the client renderer. Finally, the entire output is dumped on screen in a single go, via the renderer’s “render()” method. Of course, you shouldn’t take my explanation for granted; feel free to give the earlier script a try. If all goes well, you should see a div and a paragraph displayed on the browser, together with an alert box showing you a silly message.

I don’t need to say that the purpose of this example isn’t to teach you how to create basic HTML and JavaScript elements, as you already know how to do that (and probably much better than me). What you need to see is that the previous alert box was rendered simply by injecting an instance of its originating class into the renderer.

What’s more, there was no need to change a single portion of existing code, even though the alert box object wasn’t an HTML element itself (effectively, it doesn’t extend the abstract HTML parent). This simple concept shows quite clearly how the implementation of the “Plug-in” pattern can help to build scalable applications without having to struggle with the burden of a bad design.

Armed with this background, go ahead and start using this pattern when developing your own object-oriented applications. You’ll won’t regret it, trust me.   

Final thoughts

In this second installment of the series, I demonstrated how the functionality provided by the “Plug-in” pattern can be used for developing a fully-pluggable application that renders different types of elements on screen. In the example above, the “plug-ins” passed to the client renderer were objects that generated basic HTML/JavaScript code, and nothing else.

It’s possible, however, to inject other kinds of objects with the same ease, as long as they implement the earlier “Renderable” interface. So, if you feel adventurous and want to see if this model is this flexible, feel free to develop your own renderable class and pass an instance of it to the client renderer. Everything should work like a charm.  

Of course, the implementation of the “Plug-in” pattern isn’t only limited to displaying a few HTML elements and alert boxes, as it can be used in all sorts of environments. To prove the veracity of my statement, in the upcoming tutorial I’m going to show you how to utilize it in the development of a versatile caching system.

Don’t miss the next part!

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye