javascript装饰者模式
2010-01-31 23:28 BlueDream 阅读(836) 评论(0) 编辑 收藏 举报装饰模式:Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这两种实体在Decorator模式中是必须的.
Decorator定义:
动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.
使用Decorator的理由是:这些功能需要由用户动态决定加入的方式和时机.Decorator提供了"即插即用"的方法,在运行期间决定何时增加何种功能.
[简易实例]
<script type="text/javascript"> var f = function() { alert('原有函数'); } var _f = f; f = function() { alert('执行前置包装函数'); _f(); alert('执行后置包装函数'); } f(); </script>
[常用实例] ---- 多重onload绑定
<script type="text/javascript"> function addLoadEvent(fn) { var oldEvent = window.onload; if(typeof window.onload != 'function') { window.onload = fn; }else { window.onload = function() { oldEvent(); fn(); } } } function fn1() { alert('加载一'); } function fn2() { alert('加载二'); } function fn3() { alert('加载三'); } addLoadEvent(fn1); addLoadEvent(fn2); addLoadEvent(fn3); </script>
[扩展实例]
<script type="text/javascript"> // 被刷油漆者 Decoratee = function() { alert('被刷油漆'); } // 刷油漆工 Decorator = { beginList: [], // 前置函数列表 endList: [], // 后置函数列表 append: function(fn) { this.endList.push(fn); }, before: function(fn) { this.beginList.splice(0, 0, fn); }, wrap: function(fn/* 要被修饰的函数体 */) { var $ = this, $1 = [], $2 = []; // 包装前置函数 for(var i = 0, len = $.beginList.length; i < len; i++) { $1[i] = $.beginList[i]; } // 包装后置函数 for(var i = 0, len = $.endList.length; i < len; i++) { $2[i] = $.endList[i]; } try { return function(){ for(var i = 0, len = $1.length; i < len; i++) { $1[i](); } if(typeof fn == 'function') fn(); for(var i = 0, len = $2.length; i < len; i++) { $2[i](); } } }finally { this.beginList.length = this.endList.length = 0; } } } Decorator.before(function() { alert('刷油漆前先钉木头') }); Decorator.before(function() { alert('刷油漆前先钉钉子') }); Decorator.append(function() { alert('刷油漆后要晾干') }); Decorator.append(function() { alert('刷油漆后要涂鸦') }); Decorator.wrap(Decoratee)(); // 开始刷油漆 </script>