js 设计模式

1、单例模式:产生一个类的唯一实例

比如:点击按钮生成遮罩层->只生成一个div:先创建一个div,再调用->可能浪费:用变量判断->引入全局变量:用闭包包含->通用:单力包装器(桥接模式)

var singleton = function( fn ){
	var result;
	return function(){
		return result || ( result = fn .apply( this, arguments ) );
	}
}

var createMask = singleton( function(){
	return document.body.appendChild( document.createElement('div') );
})

2、桥接模式:实现与抽象分离

forEach的实现

forEach = function( ary, fn ){
	for ( var i = 0, l = ary.length; i < l; i++ ){
		var c = ary[ i ];
		if ( fn.call( c, i, c ) === false ){
			return false;
		}
	}
}

3、简单工厂模式:由方法决定到底要创建哪个类的实例

比如:要创建三棵树,每棵树只是容器不同,所以把创建树的方法写一个函数,创建时传入容器就行

4、观察者模式(发布-订阅模式)

(function($){
	var o = $({});

	$.subscribe = function(){
		o.on.apply(o, arguments);
	}

	$.unsubscribe = function(){
		o.off.apply(o, arguments);
	}

	$.publish = function(){
		o.trigger.apply(o, arguments);
	}

})(jQuery)

function handle(e, a, b, c){
	console.log(a+b+c);
}

$.subscribe('sfp', handle);
$.publish('sfp', ['a', 'b', 'c']);

太爽了,这应该可以解决不少问题。想不到离我这么近,需要publish才可以执行事件

5、适配器模式:很像转接口

比如:从后端传来的数据不能直接用在jsTree上,使用适配器模式,把数据转为jsTree的格式就行

设计模式是编程中的基础哲学,平时都没注意到,但无意中用了很多。

6、代理模式:为其他对象提供一种代理以控制对这个对象的访问

比如:一个对象只接受键盘事件,另一个对象负责组合键

比如:大叔 代理 dudu 给萧姑娘送花。http://www.cnblogs.com/TomXu/archive/2012/02/29/2354979.html

7、外观模式:提供一个高层接口,使得客户端更加方便调用

需要保证函数尽可能地处在一个合理粒度,提供给客户端一个高层接口,而不用管真正的细节

var stopEvent = function( e ){   
//同时阻止事件默认行为和冒泡
  e.stopPropagation();
  e.preventDefault();
}

8、访问者模式:把一些可复用的行为抽象到一个函数里,如果一个对象要调用这个函数,只需要把对象当做参数传给这个函数:call或者apply

Array构造器和String构造器的prototype上的方法就被特意设计成了访问者。这些方法不对this的数据类型做任何校验。这也就是为什么arguments能冒充array调用push方法.

9、策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换

var dataSourceVendor = { 
    xml : { 
        get : function(){ 
            console.log("XML数据源") ; 
        } 
    } , 
    json : { 
        get : function(){ 
            console.log("JSON数据源") ; 
        } 
    } , 
    csv : { 
        get : function(){ 
            console.log("CSV数据源") ; 
        } 
    } 
} ; 
console.log("选择的数据源:" + dataSourceVendor["json"]["get"]()) ; 

10、模板方法模式:预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现。

工厂模式的意图是根据子类的实现最终获得一种对象. 而模版方法模式着重于父类对子类的控制.

11、中介者模式:让各个对象之间不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互

区别:代理模式中A必然是知道B的一切,而中介者模式中A,B,C对E,F,G的实现并不关心.而且中介者模式可以连接任意多种对象。

12、迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该方法中的内部表示。

iterator

13、组合模式:部分-整理模式,将所有对象组合成树形结构。使得用户只需要操作最上层的接口,就可以对所有成员做相同的操作

比如:想取消所有节点上绑定的事件:$('body').unbind('*')

14、备忘录模式:数据缓存

比如一个分页控件, 从服务器获得某一页的数据后可以存入缓存。以后再翻回这一页的时候,可以直接使用缓存里的数据而无需再次请求服务器。

var Page = function(){
   var page = 1,
      cache = {},
      data;
   return function( page ){
      if ( cache[ page ] ){
               data =  cache[ page ];
               render( data );
      }else{
               Ajax.send( 'cgi.xx.com/xxx', function( data ){
                   cache[ page ] = data;
                   render( data );
               })
      }
    }
}()

这种函数内定义变量,再return function的用法很常见,单例模式?

15、职责链模式:js中的事件冒泡就是作为一个职责链来实现的。一个事件在某个节点上被触发,然后向根节点传递, 直到被节点捕获。

16、享元模式:减少程序所需的对象个数,可以提供一些共享的对象以便重复利用.

原理其实很简单, 把刚隐藏起来的div放到一个数组中, 当需要div的时候, 先从该数组中取, 如果数组中已经没有了, 再重新创建一个. 这个数组里的div就是享元, 它们每一个都可以当作任何用户信息的载体.

handsontable是不是也可以使用享元模式,时smooth scroll时不会缓慢

17、状态模式:状态模式主要可以用于这种场景:1 一个对象的行为取决于它的状态;2 一个操作中含有庞大的条件分支语句

var StateManager = function(){
  var currState = 'wait';
  var states = {
    jump: function( state ){
    },
    wait: function( state ){
    },
    attack: function( state ){
    },
    crouch: function( state ){
    },
    defense: function( state ){
      if ( currState === 'jump'  ){
          return false;  
//不成功,跳跃的时候不能防御
      }    
//do something;     //防御的真正逻辑代码, 为了防止状态类的代码过多, 应该把这些逻辑继续扔给真正的fight类来执行.
    currState = 'defense'; 
//  切换状态
    }
  }
  var changeState = function( state ){
    states[ state ] && states[ state ]();
  }
  return {
      changeState  : changeState
  }
}
var stateManager = StateManager();
stateManager.changeState( 'defense' );

写的真好!

  

http://blog.jobbole.com/29454/  

  

原文地址:https://www.cnblogs.com/wang-jing/p/4796734.html