浅谈javascript设计模式之工厂模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ws9029/article/details/86654650

什么是工厂模式?

我个人理解工厂模式是用来创建对象的一种最常用的设计模式,当我们创建对象时候,不暴露对象的具体逻辑,而是把它封装在一个函数里面,那我们就可以把这个函数视为工厂。工厂模式又可以根据抽象程度划分为:简单工厂,工厂方法,抽象工厂。下面我一一介绍一下这几种模式:

1.简单工厂

我个人理解简单工厂就是一个要什么我就生产什么的工厂,用代码来解释的话就好比足球类,篮球类,都放在一个函数里面,当我需要生产篮球呢,这个函数会找到我要的篮球类,我要足球,函数帮我找到足球类,其实这个函数里面就是一个类的集合。看下面代码:

//篮球类
function Basketball(){
    this.type ='basketball';
}
Basketball.prototype.size =function(){
    console.log('篮球很大')
}

//足球类
function TableTennis(){
    this.type = 'tableTennis';
}
TableTennis.prototype.size = function(){
    console.log('乒乓球很小')
}
//工厂函数
function Ball(name){
    switch(name){
        case 'basketball':
        return new Basketball();
        case 'tableTennis':
        return new TableTennis();
    }
}

var p = Ball('basketball');
console.log(p.type);//basketball
p.size();//篮球很大

当你要需要调用不用种类的类的时候,你只需要记住 Ball这个工厂对象就好了,他会帮你你要找的。简单方法的缺点就是当需求类增加,不仅要添加类,还要修改工厂函数,改两处代码,并且当类很多时会使得代码变得很庞大。

2.工厂方法

我们可以把工厂方法看成一个实例化对象的工厂类,我们将创建对象的种类放在工厂方法类的原型上,简而言之就是工厂方法是一个类(工厂方法类)。所以我们为了安全起见,我们采用安全模式类(安全模式我上篇说继承时候也提到过)。所谓安全模式可以说能屏蔽对类的错误使用所造成的错误(忘记写new关键字)。请看下面代码:

//定义球类
function Ball(){
    //安全模式
    if(!(this instanceof Ball)){
        return new Ball();
    }
}
Ball.prototype.kinds= function(){
    console.log('篮球,乒乓球等')
}

var p  = Ball();
p.kinds();

这种安全模式可以应用在我们的工厂方法中了。

// 定义球类
function Ball(type){
//安全模式
    if(this instanceof Ball){
    //找到原型上这个基类
        return new this[type];    
    }else{
        return new Ball(type);
    }
}
//原型中创建所有数据对象的基类
Ball.prototype={
    basketball:function(type){
        this.type = 'basketball';
        this.size=function(){
            console.log('篮球很大')
        }
    },
    TableTennis:function(){
        this.type = 'TableTennis';
        this.size=function(){
            console.log('乒乓球很小')
        }
    }
}

var p  =  new Ball('basketball');
console.log(p.type);//basketball
p.size();//篮球很大

工厂方式弥补了简单工厂的不足,通过工厂方法可以轻松创建多个类,我们没必要关系具体类,只需要调用工厂方式即可。

3.抽象工厂模式

抽象类式一中声明但不能使用的类,当你不正常使用时候会报错。

//创建一个抽象类
function Ball(){};
Ball.prototype ={
    getType:function(){
        return new Error('抽象方式不能调用')
    },
    getSize:function(){
        return new Error('抽象方式不能调用')  
    }
}

抽象类的作用是声明一个必备的方法,如果子类没有重写就会抛出错误。

//创建抽象工厂函数
function abstractFactory(child, parent) {
    if (typeof abstractFactory[parent] === 'function') {
        //缓存类
        function F() {};
        //继承父的属性和方法
        F.prototype = new abstractFactory[parent]();
        //子类原型继承父
        child.prototype = new F();
        //将子类constructor指向子类
        child.constructor = child;
    } else {
        throw new Error('未创建抽象类')
    }
}
//把抽象类挂在抽象工厂函数上
abstractFactory.Ball =  function Ball() {};
abstractFactory.Ball.prototype = {
    getType: function () {
        return new Error('抽象方式不能调用')
    },
    getSize: function () {
        return new Error('抽象方式不能调用')
    }
}

function Basketball(type, size) {
    this.type = type;
    this.size = '篮球很大'
    
}
//Basketball继承抽象类
abstractFactory(Basketball, abstractFactory.Ball)
//重新抽象类的getType方法
Basketball.prototype.getType = function(){
    return this.type;
}
//重新抽象类的getSize方法
Basketball.prototype.getSize = function(){
    return this.size;
}
var p = new Basketball('basketball','篮球很大')
console.log(p.getType(),p.getSize())//'basketball' '篮球很大'

我们可以通过抽象工厂,我们就能知道子类到底属于哪个抽象类,子类也就可以具备抽象类的属性和方法,我们只需要重写抽象类上的一些方法,如果我们忘记了抽象类会给很友好的报错提示。

猜你喜欢

转载自blog.csdn.net/ws9029/article/details/86654650
今日推荐