Design pattern question: encapsulation or inheritance
- by Matt
Hey all,
I have a question I have been toiling over for quite a while. I am building a templating engine with two main classes Template.php and Tag.php, with a bunch of extension classes like Img.php and String.php.
The program works like this:
A Template object creates a Tag objects. Each tag object determines which extension class (img, string, etc.) to implement.
The point of the Tag class is to provide helper functions for each extension class such as wrap('div'), addClass('slideshow'), etc.
Each Img or String class is used to render code specific to what is required, so $Img->render() would give something like <img src='blah.jpg' />
My Question is:
Should I encapsulate all extension functionality within the Tag object like so:
Tag.php
function __construct($namespace, $args) {
// Sort out namespace to determine which extension to call
$this->extension = new $namespace($this); // Pass in Tag object so it can be used within extension
return $this; // Tag object
}
function render() {
return $this->extension->render();
}
Img.php
function __construct(Tag $T) {
$args = $T->getArgs();
$T->addClass('img');
}
function render() {
return '<img src="blah.jpg" />';
}
Usage:
$T = new Tag("img", array(...);
$T->render();
.... or should I create more of an inheritance structure because "Img is a Tag"
Tag.php
public static create($namespace, $args) {
// Sort out namespace to determine which extension to call
return new $namespace($args);
}
Img.php
class Img extends Tag {
function __construct($args) {
// Determine namespace then call create tag
$T = parent::__construct($namespace, $args);
}
function render() {
return '<img src="blah.jpg" />';
}
}
Usage:
$Img = Tag::create('img', array(...));
$Img->render();
One thing I do need is a common interface for creating custom tags, ie I can instantiate Img(...) then instantiate String(...), I do need to instantiate each extension using Tag.
I know this is somewhat vague of a question, I'm hoping some of you have dealt with this in the past and can foresee certain issues with choosing each design pattern. If you have any other suggestions I would love to hear them.
Thanks!
Matt Mueller