php example
<?php /** * The smallest cohesive interface we can think of for this type * of Decorator. This is the Component interface. */ interface HtmlElement { /** * @return string html code */ public function __toString(); /** * @return string the name of the POST request key for this element, * aka the "name" attribute. */ public function getName(); } /** * Represents a <input type="text" /> html element. * It can be created programmatically and then printed. * This is the only ConcreteComponent. */ class InputText implements HtmlElement { protected $_name; public function __construct($name) { $this->_name = $name; } public function getName() { return $this->_name; } public function __toString() { return "<input type=\"text\" id=\"{$this->_name}\" name=\"{$this->_name}\" />\n"; } } /** * Very simple base class to share the wrapping code between Decorators. * This is the Decorator participant. */ abstract class HtmlDecorator implements HtmlElement { protected $_element; public function __construct(HtmlElement $input) { $this->_element = $input; } /** * All operations are delegated by default, not changing anything * of the original behavior. * ConcreteDecorators will override the methods they are interested in. */ public function getName() { return $this->_element->getName(); } public function __toString() { return $this->_element->__toString(); } } /** * Adds a custom <label> element alongside the <input> one. * Example of ConcreteDecorator. */ class LabelDecorator extends HtmlDecorator { protected $_label; public function setLabel($label) { $this->_label = $label; } public function __toString() { $name = $this->getName(); return "<label for=\"{$name}\">{$this->_label}</label>\n" . $this->_element->__toString(); } } /** * Adds a <span> containing an error message after the <input> element. * Example of ConcreteDecorator. */ class ErrorDecorator extends HtmlDecorator { protected $_error; public function setError($message) { $this->_error = $message; } public function __toString() { return $this->_element->__toString() . "<span>{$this->_error}</span>\n"; } } $input = new InputText('nickname'); $labelled = new LabelDecorator($input); $labelled->setLabel('Nick:'); echo "Using labelDecorator => \n",$labelled, "\n"; $input = new InputText('nickname'); $error = new ErrorDecorator($input); $error->setError('You must enter a unique nickname'); echo "Using errorDecorator => \n",$error, "\n"; // how can we obtain a LabelledErrorInputText, which has both the <label> // and <span> elements? $input = new InputText('nickname'); $labelled = new LabelDecorator($input); $labelled->setLabel('Nick:'); $error = new ErrorDecorator($labelled); // a Decorator wrapping another one $error->setError('You must enter a unique nickname'); echo "Using both labelDecorator & errorDecorator => \n".$error; ?> Output : Using labelDecorator => <label for="nickname">Nick:</label> <input type="text" id="nickname" name="nickname" /> Using errorDecorator => <input type="text" id="nickname" name="nickname" /> <span>You must enter a unique nickname</span> Using both labelDecorator & errorDecorator => <label for="nickname">Nick:</label> <input type="text" id="nickname" name="nickname" /> <span<You must enter a unique nickname>/span>
Some code in java
interface iComponent { public void doStuff(); } class component implements iComponent { public void doStuff() { System.out.println("component does stuff"); } } interface decorator extends iComponent { public void addedBehaviour(); } class concreteDecorator implements decorator { iComponent comp; public concreteDecorator(iComponent comp) { super(); this.comp = comp; } public void addedBehaviour() { System.out.println("Added behaviour in decorator"); } public void doStuff() { comp.doStuff(); addedBehaviour(); } } class concreteDeco2 implements decorator { iComponent comp; public concreteDeco2(iComponent comp) { super(); this.comp = comp; } public void addedBehaviour() { System.out.println("Added behaviour in deco no 2"); } public void doStuff() { comp.doStuff(); addedBehaviour(); } } public class decoClient { public static void main(String[] args) { iComponent comp = new component(); decorator deco = new concreteDecorator(comp); deco.doStuff(); decorator deco2 = new concreteDeco2(comp); deco2.doStuff(); } } Output : component does stuff Added behaviour in decorator component does stuff Added behaviour in deco no 2
2 comments:
this is a very good demonstration of decorator pattern
Main benefit of decorator is that it affect only individual object and not all object which itself a big control and flexibility inheritance doesn't offer.
Post a Comment