In fact, solving the seemingly-complex scenario discussed in the previous section is ridiculously simple, thanks to the use of the "Plug-in" paradigm. Remember that at the beginning, I stated that this pattern often requires the use of an interface? Well, to make the earlier renderer accept any type of "renderable" object, the first change that I'm going to introduce will be the incorporation of a new interface, not surprisingly called "Renderable" as well.
The interface looks like this:
Even though the definition of the above interface seems to be a rather irrelevant fact at first glance, the impact that it introduces into the "plugability" of the previous rendering application is remarkable. Not convinced yet? Then take a look at the revamped implementations of the following HTML classes, which should make you change your mind:
abstract class AbstractHtmlElement
class Div extends AbstractHtmlElement implements RenderRenderable
class Paragraph extends AbstractHtmlElement implements RenderRenderable
A couple of interesting things are happening here. The first one is the definition of a whole new class called "Paragraph," which is responsible for returning to client code the markup corresponding to the identically-named HTML element. The second one, and by far the most relevant, is that this class and the earlier "Div" are now implementers of the "Renderable" interface, while at the same time extending the functionality of its abstract parent.
This apparently subtle change is actually the soul and body of the "Plug-in" pattern. It allows you to create client classes that can be fed any type of "renderable" element, not only the ones that display HTML code. This concept can be seen more clearly in the enhanced implementation of the "Renderer" class. Take a peek at it:
Effectively, the renderer now takes, through its "addElement()" method, any object that implements the "Renderable" interface. In this way, it implements a truly "pluggable" system whose functionality can be extended via third-party classes. At this point, do you spot the benefits of implementing the "Plug-in" pattern in PHP? I guess you do!
However, the best way to see if my claim is really true is by creating an example that uses the amended versions of the previous classes. That's precisely what I plan to do in the following section, so keep reading.
Seeing the plug-in pattern in action: building a final example
If you're anything like me, you want to see a concrete example that puts the earlier classes (and the "Renderable" interface, of course) to work side by side. Below I created a simple one for you, which shows in a nutshell the functionality of the "Plug-in" pattern. Here it is:
use HtmlDiv as Div,
// create some HTML elements
// create the renderer and add the previous elements to it
/* displays the following
<div id="one_id" class="one_class">This is the sample content for the div element.</div>
While it's valid to point out that the output generated by the above script is pretty primitive (after all, it simply echoes a div and a paragraph to the browser), it illustrates how the use of the "Plug-in" pattern permits you to create applications that can be easily extended. In the previous example, a couple of renderable HTML objects have been passed to an instance of the "Renderer" class.
It's also possible, however, to feed the pertinent class any other kind of renderable element, such as an object that generates PDF content, or one that renders JPG, GIF and PNG images. I guess you get the picture. And best of all, this enhancement process can be accomplished without having to refactor the implementation of the renderer.
So what are you waiting for? Build your own renderable objects and inject them into the generic renderer. You'll be more than pleased with the results that you'll get, believe me.
In this first part of the series, I provided you with a quick introduction to the key concepts that surround the implementation of the Plug-in design pattern in PHP, and also showed how to take advantage of its benefits for building an easily extensible application. In this case, the sample program rendered on screen a few simple HTML widgets, such as divs and paragraphs, but this functionality can be easily extended to other elements as well.
Don't miss the next tutorial!
Articles in this series
blog comments powered by Disqus