20190408 期
设计模式 - 如何理解工厂模式?
定义: 创建对象的接口,让子类决定实例化哪个类。工厂方法将类的实例化延迟到子类, 而子类可以重写接口方法以便创建的时候指定自己的对象类型。
适用场景
需要根据不同参数产生不同实例,这些实例都有相同的行为, 这时候我们可以使用工厂模式,简化实现的过程,同时也可以减少每种对象所需的代码量。工厂模式有利于消除对象间的耦合,提供更大的灵活性
代码理解:
// 下方就是一个典型的工厂模式
// 首先创建对象的接口
const productManager = {};
productManager.createProductA = function () {
console.log(‘ProductA’);
}
productManager.createProductB = function () {
console.log(‘ProductB’);
}
productManager.factory = function (type) {
// 工厂方法将类的实例化延迟到子类
return new productManager[type];
}
// 让子类决定实例化哪个类
productManager.factory(“createProductA”);
如果还不理解的话,那我们就再详细一点咯,假如我们想在网页面里插入一些元素,而这些元素类型不固定,可能是图片,也有可能是连接,甚至可能是文本,根据工厂模式的定义,我们需要定义工厂类和相应的子类,我们先来定义子类的具体实现(也就是子函数)
var page = page || {};
page.dom = page.dom || {};
// 子函数 1:处理文本
page.dom.Text = function () {
this.insert = function (where) {
var txt = document.createTextNode(this.url);
where.appendChild(txt);
};
};
// 子函数 2:处理链接
page.dom.Link = function () {
this.insert = function (where) {
var link = document.createElement(‘a’);
link.href = this.url;
link.appendChild(document.createTextNode(this.url));
where.appendChild(link);
};
};
// 子函数 3:处理图片
page.dom.Image = function () {
this.insert = function (where) {
var im = document.createElement(‘img’);
im.src = this.url;
where.appendChild(im);
};
};
那么我们如何定义工厂处理函数呢?其实很简单:
page.dom.factory = function (type) {
return new page.dom[type];
}
使用方式如下:
var o = page.dom.factory(‘Link’);
o.url = ‘http://www.cnblogs.com’;
o.insert(document.body);
熟悉的 jquery
jQuery 中的 $() 其实就是一个工厂函数,它根据传入参数的不同创建元素或者去寻找上下文中的元素,创建成相应的 jQuery 对象
// https://github.com/jquery/jquery/blob/master/src/core/init.js
init = jQuery.fn.init = function(selector, context, root) {
var match, elem;
// HANDLE: $(“”), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
// Method init() accepts an alternate rootjQuery
// so migrate can support jQuery.sub (gh-2101)
root = root || rootjQuery;
// Handle HTML strings
if (typeof selector === “string”) {
//…
// HANDLE: $(DOMElement)
} else if (selector.nodeType) {
//….
// HANDLE: $(function)
// Shortcut for document ready
} else if (jQuery.isFunction( selector) ) {
//….
}
return jQuery.makeArray(selector, this);
};
总结
优点
工厂类含有必要的判断逻辑, 实现了对责任的分割,它提供了专门的工厂类用于创建对象
用户只需要关心所需产品对应的工厂,无须关心创建细节
在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口, 符合“开闭原则”
缺点
添加新产品时,需要编写新的具体产品类, 一定程度上增加了系统的复杂度
考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度
关于 JS 每日一题
JS 每日一题可以看成是一个语音答题社区 每天利用碎片时间采用 60 秒内的语音形式来完成当天的考题 群主在次日 0 点推送当天的参考答案
注 绝不仅限于完成当天任务,更多是查漏补缺,学习群内其它同学优秀的答题思路
点击加入答题