给我一张名片————工厂模式
工厂方法模式(Factory Method): 通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例
4.1 广告的展现
由于有广告资源的投放, 一批是JAVA的,用绿色字体;一批是PHP,用黄色字体,红色背景
start
// 创建 Java 学科
var Java = function(content){
// 将内容保存在 content 里面以备日后使用
this.content = content;
// 创建对象时,通过闭包,直接执行,将内容按需求的样式插入到页面中
(function(content){
var div = document.createElement('div');
div.innerHTML = content;
div.style.color = 'green';
document.getElementById('container').appendChild(div);
})(content);
}
// 创建 PHP 学科类
var PHP = function(content){
this.content = content;
(function(content){
var div = document.createElement('div');
div.innerHTML = content;
div.style.color = 'yellow';
div.style.backgroundColor = 'red';
document.getElementById('container').appendChild(div);
})(content)
}
又来一个需求 javascript的,背景色是 粉色
突然想起来昨天学习的简单工厂模式,是不是用它实现一下呢?
// 创建 Java 学科类
var Java = function(content){}
// 创建 PHP 学科类
var PHP = function(content){}
// 创建 javascript 学科类
var Javascript = function(content) {
this.content = content;
(function(content){
var div = document.createElement('div');
div.innerHTML = content;
div.style.backgroundColor = pink;
document.getElementById('container').appendChild(div);
})(content)
}
// 学科工厂类
function JobFactory(type, content) {
switch(type) {
case 'java' :
return new Java(content);
case 'PHP' :
return new PHP(content);
case 'javascript' :
return new Javascript(content);
}
}
// 写一个测试案例
JobFactory('javascript', 'javascript哪家强');
又来一个需求,em.......
4.2方案的抉择
在JAVASCRIPT中实现工厂方法模式我们只需要参考它的核心思想即可。我们可以将工厂方法看做是一个实例化对象的工厂类。安全起见,我们使用安全模式类,而我们将创建对象的基类放在工厂方法类的原型中即可。
4.3 安全模式类
什么是安全模式类呢?
安全模式类是说可以屏蔽使用这对类的错误使用造成的错误。 比如说对于一个类(我们暂时称为 Demo 类)的创建,我们知道类的前面是需要有new关键字的(如 var d = new Demo() ), 不过其他人不知道这个对象(Demo)是一个类,那么在使用时很可能会忽略 new 关键字直接执行类 (如var d = Demo() ), 此时我们得到的并不是我们预期的对象。
var Demo = function(){};
Demo.prototype = {
show : function(){
console.log('成功获取');
}
}
var d = new Demo();
d.show(); // 成功获取
var d = Demo();
d.show(); // Uncaught TypeError: Cannot read property 'show' of undefined
安全模式可以解决这种问题。这也是避免像你一样的那些新来的同学可能犯的错误。
当然解决方案很简单,就是你在构造函数的时候先判断当前对象 this 指代的是不是类(Demo),如果通过 new 关键字创建的对象,如果不是说明类在全局作用域中执行(通常情况下), 那么既然在全局作用域中执行的当然 this 就会指向 window 了(通常情况下, 如非浏览器的情况可为其他全局对象)这样我们就要 返回新创建的对象了
var Demo = function(){
if( !this instanceof Demo ){
return new Demo();
}
}
var d = Demo();
d.show(); // 成功获取
有了安全模式 我们就可以将这种技术应用到我们的工厂模式中了
4.4 安全的工厂模式
// 安全模式创建的工厂类
var Factory = function(type, content){
if( this instanceof Factory ){
var s = new this[type](content);
return s;
} else {
return new Factory(type, content);
}
}
// 工厂原型中 设置创建所有的类型数据对象的基类
Factory.prototype = {
Java : function(content){},
PHP : function(content){},
Javascript : function(content){},
UI : 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)
}
}
这样我们以后想要添加其他类的时候, 是不是就只需要写在Factory这个工厂类的原型里面就可以了?
嗯,是这样的,你再也不用担心创建时做任何修改。就好比你在 Factory 类的原型里面注册了一张名片以后你需要哪类直接拿着这张名片。查找上面的信息就可以找到这个类了。
又来需求了,一堆添加广告的数据
var data = [
{type :'Javascript', content :'javascript'},
{type :'Java', content :'Java哪家强'},
{type : 'php', content :'php哪家强'},
{type : 'UI', content :'UI哪家强'},
{type :'Javascript', content :'Javascript哪家强'},
{type :'Javascript', content :'Javascript哪家强'},
]
面对这些需求,开始
for(var i = 6; i >= 0; i--){
Factory(s[i].type , s[i].content)
}