小白学习JavaScript设计模式(2)——工厂方法模式

在说工厂方法模式之前先说一下安全模式类

什么是安全模式类,安全模式类就是说可以屏蔽使用这对类的错误使用造成的错误,这听起来有点不容易理解,那下面举一个例子。

现在我们创建了一个Dome类如下:

var Dome = function(text){
    this.text = text;
}
Dome.prototype = {
    show:function(){
        console.log(this.text);
    }
}

如果我们要使用这个Dome类必须要使用new关键字来执行(var d = new Dome()),但是有时往往会忽略掉new关键字(var d = Dome()),此时当我们调用Dome类的show()方法时会出现如下错误。

//Uncaught TypeError:Connot read property 'show' of undefined

我们有一种简单的解决方案:在构造函数开始时先判断当前的this指代是不是类(Dome),如果是则通过new关键字创建对象,如果不是说明类在全局域中执行,即只想window。代码如下:

var Dome  = function(content){
    if(!(this instanceof Dome)){
        return new Dome(content);
    }
}

Dome.prototype = {
    show:function(){
        console.log("获取成功");
    }
}

var d1 = Dome();
d1.show();  //获取成功

//或者
var d2 = new Dome();
d2.show();  //获取成功

 工厂方法模式

工厂方法模式是将实际创建的对象工作推迟到子类当中,这样核心类就成了抽象类。

举个例子:现在需要做一些课程培训的广告,包括JS、HTML、CSS三个部分,他们分别采用不同的背景颜色。如果按照原来的简单工厂模式的思想,我们首先需要创建对应的3个类,如下:

//创建JS类
        var JS = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid red';
                document.getElementById("container").appendChild(div);
            })(content);
        };
        //创建JS类
        var HTML = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid yellow';
                document.getElementById("container").appendChild(div);
            })(content);
        };
        //创建JS类
        var CSS = function (content) {
            this.content = content;
            (function (content) {
                var div = document.createElement('div');
                div.innerHTML = content;
                div.style.border = '1px solid green';
                document.getElementById("container").appendChild(div);
            })(content);
        };

function JobFactory(type, content) {
            switch (type) {
            case 'JS':
                return new Js(content);
            case 'HTML':
                return new HTML(content);
            case 'CSS':
                return new CSS(content);
            }
        }

我们可以看到这样写出来的代码量很大,并且当每次要增加需求的时候我们都至少要修改两个地方,这显然降低了效率。

那么接下来我们看一下工厂方法模式的优势所在,直接上代码:

var Factory = function (type, content) {
            if (this instanceof Factory) {
                var s = new this[type](content);
                return s;
            } else {
                return new Factory(type, content);
            }
            this.content = content;
        };
Factory.prototype = {
            JS: function (content) {
                //                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid green';
                    document.getElementById("container").appendChild(div);
                })(content);
            },
            CSS: function (content) {
                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid red';
                    document.getElementById("container").appendChild(div);
                })(content);
            },
            HTML: function (content) {
                this.content = content;
                (function (content) {
                    var div = document.createElement('div');
                    div.innerHTML = content;
                    div.style.border = '1px solid yellow';
                    document.getElementById("container").appendChild(div);
                })(content);
            }
        }

        var data = [
            {
                type: 'HTML',
                content: "HTML"
            }, {
                type: 'CSS',
                content: "CSS模块"
            }, {
                type: 'JS',
                content: "JS模块"
            }, {
                type: 'JS',
                content: "JS模块"
            }, {
                type: 'CSS',
                content: "CSS模块"
            }
        ];
        for (var i = 0; i < data.length; i++) {
            Factory(data[i].type, data[i].content);
        }

直观的看上去貌似代码量比原来的还要多,那是因为我们这里显示了5条数据,并且增加了安全模式验证。

我们来分析一下代码,看看有哪些不同的地方。

最大的不同是我们把所有的子类改成了一个工厂类的原型方法中,这样做的好处可以减少代码的污染,得到了很好的封装,现在如果遇到了需求变更,我们只需要在这个工程类中增加或删除对应的方法即可。

猜你喜欢

转载自blog.csdn.net/DengZY926/article/details/83022197