您的位置:首页 > Web前端 > JavaScript

JavaScript设计模式学习笔记

2016-01-28 22:52 676 查看
设计模式可以帮助我们更好的解决一类问题,重复代码。

下面学习一下作为一名前端工程师应该掌握的设计模式:

1.单体模式,也叫单例模式

其实就是把自己的代码的作用变量全部放到一个命名空间下面,以便日后的维护和避免全局变量的使用。

var functionGroup = {
name:'sufubo',
method1:function  () {
//code
},
init:function  () {
// body...
}
}


大概就是这个样子就是单例模式。

2.工厂模式。就是把你要用的一部分功能专门交给一个对象去做,就好像这部分功能是他生产的一样,所以也叫做工厂模式。

//工厂模式
var XMLHttpFactory = function  () {};
XMLHttpFactory.createXMLHttp = function  () {
var XMLHttp = null;
if(window.XMLHttpRequest){
XMLHttp = new XMLHttpRequest();
}else if(window.ActiveXObject){
XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
return XMLHTTP;
}
var AjaxHandler = function(){
var XMLHttp = XMLHttpFactory.createXMLHttp();
//code
}


3.桥梁模式,这个也是js中常用的一种模式,把抽象和实现隔离开来的一种方式。其实经常用:

element.onclick = function  () {
new eventHandler(element,param,callback);
}


这种回调函数的模式就是桥接模式,在里面的处理函数中。尽可能多的暴露api,让里面的行为可控。

4.装饰者模式

就是为对象添加一些属性,所以叫装饰

var myText = {};
myText.Decoration = {};
myText.Core = function  (myString) {
this.show = function  () {
return myString;
}
}
//装饰
myText.Decoration.addQuestuibMark = function  (myString) {
this.show = function(){return myString.show()+'?';};
}


5.门面模式

这是所有js的库,或者我们自己写的函数都会用到的准则。就是把功能都封装在内部,只给外部暴露相应的接口操作就行了,看了下面的例子,你会马上明白。

var addEvent = function(el,type,fn){
if(window.addEventListener){
el.addEventListener(type,fn);
}else if(window.attachEvent){
el.attachEvent('on'+type,fn);
}else{
el['on'+type] = fn;
}
}


这就相当于一个门面了。只对外面暴露了一些接口。

6.适配器模式

顾名思义就是把一种接口模式转化为另外一种模式。就是跟适配器一样进行转换,看下面这个例子:

var strObj = {
str1:"str1",
str2:"str2",
str3:"str3"
}
function interfaceMethod(str1,str2,str3){
console.log(str1);
}
//适配器函数
function adapterMethod (o) {
interfaceMethod(o.str1,o,str2,o.str3);
}
adapterMethod(strObj);


7.享元模式

就是把多个使用同一个操作的对象封装成由(1)享元(抽离出来的外部对象和数据)(2)工厂(创造对象的工厂)(3)存储器(存储实例的对象和数组,供享元统一控制和管理)

下面的是我摘录别人的说的比较正规:

*应用场景

页面存在大量资源密集型对象;

这些对象具备一定的共性,可以抽离出公用的操作和数据

关键

合理划分内部和外部数据。

既要保持每个对象的模块性、保证享元的独立、可维护,又要尽可能多的抽离外部数据。

管理所有实例

既然抽离出了外部数据和操作,那享元就必须可以访问和控制实例对象。在JavaScript这种动态语言中,这个需求是很容易实现的:我们可以把工厂生产出的对象简单的扔在一个数组中。为每个对象设计暴露给外部的方法,便于享元的控制。

优点

将能耗大的操作抽离成一个,在资源密集型系统中,可大大减少资源和内存占用;

职责封装,这些操作独立修改和维护;

缺点

增加了实现复杂度。

将原本由一个工厂方法实现的功能,修改为了一个享元+一个工厂+一个存储器。

对象数量少的情况,可能会增大系统开销。*

示例:

//汽车登记示例
var Car = function(make,model,year,owner,tag,renewDate){
this.make=make;
this.model=model;
this.year=year;
this.owner=owner;
this.tag=tag;
this.renewDate=renewDate;
}
Car.prototype = {
getMake:function(){
return this.make;
},
getModel:function(){
return this.model;
},
getYear:function(){
return this.year;
},
transferOwner:function(owner,tag,renewDate){
this.owner=owner;
this.tag=tag;
this.renewDate=renewDate;
},
renewRegistration:function(renewDate){
this.renewDate=renewDate;
}
}
//数据量小到没多大的影响,数据量大的时候对计算机内存会产生压力,下面介绍享元模式优化后
//包含核心数据的Car类
var Car=function(make,model,year){
this.make=make;
this.model=model;
this.year=year;
}
Car.prototype={
getMake:function(){
return this.make;
},
getModel:function(){
return this.model;
},
getYear:function(){
return this.year;
}
}
//中间对象,用来实例化Car类
var CarFactory=(function(){
var createdCars = {};
return {
createCar:function(make,model,year){
var car=createdCars[make+"-"+model+"-"+year];
return car ? car : createdCars[make + '-' + model + '-' + year] =(new Car(make,model,year));
}
}
})();
//数据工厂,用来处理Car的实例化和整合附加数据
var CarRecordManager = (function() {
var carRecordDatabase = {};
return {
addCarRecord:function(make,model,year,owner,tag,renewDate){
var car = CarFactory.createCar(make, model, year);
carRecordDatabase[tag]={
owner:owner,
tag:tag,
renewDate:renewDate,
car:car
}
},
transferOwnership:function(tag, newOwner, newTag, newRenewDate){
var record=carRecordDatabase[tag];
record.owner = newOwner;
record.tag = newTag;
record.renewDate = newRenewDate;
},
renewRegistration:function(tag,newRenewDate){
carRecordDatabase[tag].renewDate=newRenewDate;
},
getCarInfo:function(tag){
return carRecordDatabase[tag];
}
}
})();


8.观察者模式

就是观察者观察被观察者有什么变换,而去产生什么处理。这种模式在js事件处理中比较常见

//使用时间监听器可以让多个函数相应一个事件
var fn1 = function(){
//code
}
var fn2 = function(){
//code
}
addEvent(element,'click',fn1);
addEvent(element,'click',fn2)
//而时间处理函数就办不到
element.onclick = fn1;
element.onclick = fn2;


9.命令模式

把命令封装成不同的对象,根据传进去参数的不同,使用不同的方法。

car Calculator={
add:function(x,y){
return x+y;
},
substract:function(x,y){
return x-y;
},
multiply:function(x,y){
return x*y;
},
divide:function(x,y){
return x/y;
}
}
Calculator.calc = function(command){
return Calculator[command.type](command.op1,command.opd2)
};
Calculator.calc({type:'add',op1:1,op2:1});
Calculator.calc({type:'substract',op1:5,op2:2});
Calculator.calc({type:'multiply',op1:5,op2:2});
Calculator.calc({type:'divide',op1:8,op2:4});


这是我理解的几种模式,其他还有好多的设计模式。暂时没用到过,还不太理解就不说了。

原文js设计模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息