JavaScript工厂模式

JavaScript工厂模式

1.简单工厂模式

简单工厂模式的概念就是创建对象,将我们需要使用的方法封装在一个函数中,通过这个函数调用并创建新的方法的实例,也就是说我们不需要显式的new一个新的实例,工厂模式自动返回新的实例化对象。

//假设有一个大型奥运会比赛,通过工厂模式将其封装在奥运会的工厂模式中
function OlympicsFactory(sports){
    switch(sports){
        case 'Basketball':
            return new Basketball();
        case 'Football':
            return new Football();
        case 'Swim':
            return new Swimming();
    }
}
//创建具体的运动类型,主要用于表示不同的类型的方法用于干什么的
var Basketball = function(){
    console.log("This is BasketBall Sports");
}
var Football = function(){
    console.log("This is Football Sports");
}
var Swim = function(){
    console.log("This is Swimming Sports");
}
//调用方法
OlympicsFactory(Football); 

分析:使用上面的方式有一个缺点:当上面运动的方法中有相同的属性时,就会创建相同的属性代码,比如运动会的时间,地点以及参与人数等,这会造成程序的冗余度较高。这时我们可以在工厂函数中封装相同的属性代码。

function OlympicsFactory(sports,location,time,participants){
    var o = new Object();
    //相同部分
    o.time = time;
    o.location = location;
    o.participants = participants;
    o.getDetails = function(){
        console.log("This is" + sports + "Sports");
    }
    //不同部分
    if(sports == 'Basketball'){
        o.属性 = 属性值;
    }
    if(sports == 'Football'){
        o.属性 = 属性值;
    }
    if(sports == 'Swimming'){
        o.属性 = 属性值;
    }
        return o; 
} 
     //调用工厂函数返回实例化对象 
var Basketball = OlympicsFactory("Basketball", "Brasil", "2016", "5000"); 

两种方式根据实际情况使用,如果项目中没有共有属性和方法,第一种最好,如果项目中共有方法属性过多,第二种方法最适合。
更安全的简单工厂模式(也叫工厂方法模式《JavaScript设计模式》里的概念):在以上第一种方法中,如果要添加一项新的运动,如跳水,我们需要在工厂函数中创建diving的case,也需要在外部创建具体的运动类型,这样每添加一个类就要修改两个地方,多一个操作就会多一分危险,而且我们创建的工厂函数是被封装好了的,其他的开发人员并不知道我们创建工厂函数使用的是funciton关键字还是new操作符,所以他们在调用此工厂方法时可能会用new关键字实例化一个新的工厂方法模式。所以改进代码如下:

//判断this的指向,如果this指向OlympicsFactory,直接调用即可,如果不是,实例化一个新的OlympicsFactory方法
var OlympicsFactory = function (sports, content){ 
    if(this instanceof OlympicsFactory){
        return new this[sports](content);
    } else {
        return new OlympicsFactory(sports, content);
    }    
};    
//将OlympicsFactory方法的所有内部属性或放阿飞封装在OlympicsFactory方法的原型中,如果需要添加新的sports,只需要在原型中添加就可    
OlympicsFactory.prototype = {        
    Basketball: function(content){            
    console.log("This is " + content + " Sports");       
},       
Football: function(content){            
    console.log("This is " + content + " Sports");        
},        
Swimming: function(content){            
    console.log("This is " + content + " Sports");        
},        
//新增diving跳水运动        
Diving: function(content){            
    console.log("This is " + content + " Sports");        
}    
};    
//调用方法    
var a = OlympicsFactory("Football", "exciting");    
var b = new OlympicsFactory("Baseketball", "dangering");

2.抽象工厂模式

从简单工厂模式我们不难得出,创建运动类型就就像是继承一样,继承OlympicsFactor函数里的方法。而简单工厂模式在函数内部定义了一个闭包,当我们修改这个闭包,即添加新的实例基类时,需要对这个闭包做出相应的更改,违背了闭包的只读原则,所以抽象工厂模式是一种更优化的设计模式,我们只需要知道要创建的子类和父类的名称,调用抽象工厂方法使子类继承父类的属性和方法。

//type表示运动类型,如球类var OlympicsFactory = function (sports, type){    
if(typeof OlympicsFactory[type] == 'function'){        
    function F(){};                  
    //创建一个F类用于中间变量,用于继承OlympicsFactory的属性和方法,从而将这些属性方法再继承给子类sports        
    F.prototype = new OlympicsFactory[type]();                         
    sports.constructor = sports;                 
    sports.prototype = new F();          
    //继承F继承的属性和方法,重写了sports.prototype属性    
    } else {        
    throw new Error('出错!');    
    }
};
//创建Basketball子类,它属于Ball类运动。
var Basketball = function(time, location){    
    this.time = time;    
    this.location = location;
}
//调用抽象工厂方法,实现对Ball的继承
OlympicsFactory(Basketball, 'Ball');
Basketball.prototype.getTime = function(){    
    return this.time;
}
Basketball.prototype.getLocation = function(){    
    return this.location;
}
//调用
var basketlball = new Basketball("2016", "Brazil");
console.log(basketball.getTime);    

抽象工厂模式的好处是当我们想要新创建一个子类时,不必在模式定义的函数内部创建,直接通过继承实现子类所在的父类对象的属性和方法,所以抽象工厂模式返回的不是对象的实例,而是实例所属的类。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值