今天打算开始系统的学习设计模式,虽然之前有看过《大话设计模式》但是没能够静下心来写学习笔记导致很多内容都只是有一个概念而不会去应用。这次要记下学习的过程。接下来进入主题。
何为设计模式?设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
今天学习的是装饰者模式,该模式是一种结构型的模式,它与对象的创建无关,主要是考虑到如何扩展对象的功能。我们除了使用线性的继承方式,还可以使用创建若干个装饰的对象来扩展其功能,当我们面对不同的需求的时候,我们可以用该模式,自行选择不同的装饰器不同的顺序来执行方法。
接下来我们来举个例子,比如说装饰一个圣诞树,首先先有一棵圣诞树
1 var tree={};
有了圣诞树之后我们就要装饰它,接下来实现装饰的动作
tree.decorate=function(){ console.log('this is a tree'); }
动作有了,但是还没有被装饰的物件(装饰器)接下来创建几个属于圣诞树的装饰品
tree.BlueBalls=function(){ this.decorate=function(){ this.BlueBalls.prototype.decorate(); console.log('BlueBalls') } } tree.Angel=function(){ this.decorate=function(){ this.Angel.prototype.decorate(); console.log('Angel') } } tree.RedBalls=function(){ this.decorate=function(){ this.RedBalls.prototype.decorate(); console.log('RedBalls') } }
我们现在有了圣诞树,装饰圣诞树的动作,装饰圣诞树装饰品,还不行,还需要一个获取装饰品的方法
tree.getDecorator=function(deco){
tree[deco].prototype=this;
return new tree[deco];
}
所有的东西都准备好了可以装饰圣诞树了
tree=tree.getDecorator('BlueBalls'); tree=tree.getDecorator('Angel'); tree=tree.getDecorator('RedBalls'); tree.decorate(); console.log('tree',tree)
执行完上面的语句在控制台可以看到打印了以下文字
如果把装饰语句换成以下顺序呢
从图中可知语句的顺序的不同,得出的方法的执行顺序也不同。
总结:装饰者模式需要四个步骤组成 被装饰者装饰品,被装饰的动作,获取装饰品的动作,
细看代码不难发现装饰品中的也有decorate方法,不难看出该方法是在被装饰品的方法执行之后执行的,而且继承于被装饰品。获取装饰品的方法其实就是将装饰品的decorate方法叠加在被装饰品的decorate方法之上。使得方法之间成为一种继承关系。
由于好奇我将tree对象打印出来,得出 getDecorator()使用了几次 就会有几成的继承关系 。以下是例子的源码。
<script type="text/javascript"> var tree={}; tree.decorate=function(){ console.log('this is a tree'); } tree.getDecorator=function(deco){ this[deco].prototype=this; return new tree[deco]; } tree.BlueBalls=function(){ this.decorate=function(){ this.BlueBalls.prototype.decorate(); console.log('BlueBalls') } } tree.Angel=function(){ this.decorate=function(){ this.Angel.prototype.decorate(); console.log('Angel') } } tree.RedBalls=function(){ this.decorate=function(){ this.RedBalls.prototype.decorate(); console.log('RedBalls') } } tree=tree.getDecorator('BlueBalls'); tree=tree.getDecorator('Angel'); tree=tree.getDecorator('RedBalls'); tree.decorate(); console.log('tree',tree) </script>