环境
动态的给一个对象添加一些功能扩展 汽车的组装(汽车安装GPS、雷达等等)
详解
-
角色:装饰者(decorator)、被装饰者(decoratee)
-
component 抽象父类 ConcreteComponent 子类 将要动态的加上新行为的对象 Decorator 装饰者 配件 抽象 父类 ConcreteDecoratorA 装饰子类A ConcreteDecoratorB 装饰子类B
php
<?php /** * Created by PhpStorm. * User: zhang * Date: 2016/10/25 * Time: 19:20 */ abstract class Beverage{ public $_name; abstract public function cost(); } class Coffee extends Beverage{ public function __construct() { $this->_name = "coffee"; } public function cost() { // TODO: Implement cost() method. return 1; } } class CondimentDecrator extends Beverage{ public function __construct() { $this->_name = 'Condiment'; } public function cost() { // TODO: Implement cost() method. return 0.1; } } class Milk extends CondimentDecrator{ public $_beverage; public function __construct($beverage) { $this->_name = 'Milk'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else{ exit('failure'); } } public function cost() { // return parent::cost(); // TODO: Change the autogenerated stub return $this->_beverage->cost()+0.3; } } class Sugar extends CondimentDecrator{ public $_beverage; public function __construct($beverage) { $this->_name = 'Sugar'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else{ exit('failure'); } } public function cost() { // return parent::cost(); // TODO: Change the autogenerated stub return $this->_beverage->cost()+0.5; } } $coffee = new Coffee(); $coffee = new Milk($coffee); $coffee = new Sugar($coffee); printf("coffee total %0.2f",$coffee->cost());
javascript 装饰者模式:在不改变原对象的基础上,通过对其进行包装拓展(添加属性或者方法)使原有对象可以满足用户的更复杂需求。
<div> <input type="text" id="tel" name="tel"> <span id="warn">1</span> </div> var telInput = document.getElementById('tel'); var warnSpan = document.getElementById('warn'); telInput.onclick = function() { // warnSpan.style.display = "none"; warnSpan.innerText = ''; } //装饰者 var decorator = function(input,fn) { var input = document.getElementById(input); if(typeof input.onclick === 'function') { var oldClickFn = input.onclick; input.onclick = function(){ oldClickFn(); fn(); } }else{ input.onclick = fn; } } decorator('tel',function(){ warnSpan.innerText = '2'; })