一、适用场景
简单工厂模式
是一种创建型模式
,适用于创建同一类对象。
假如存在以下需求:
编写一系列的弹出框,包括:警告框(alert)、输入框(promt)、确认框(confirm)
我们自然可以编写Alert()
、Prompt()
、Confirm()
三个类,然后每次调用时,使用new Alert()
、new Prompt()
来调用。这在大多数情况下当然没有什么问题,但是假如有一天我们对警告框做了一些改进,然后把它命名为BetterAlert()
,但此时项目里已经大量使用Alert()
了,如此一来我们如果要应用BetterAlert()
,就涉及很多地方的更改。如何解决这个问题?
二、核心思想
简单工厂模式
的核心思想就是抽象出一个工厂函数
,工厂函数内部通过传入的参数进行判断应该实例化和使用哪些类,使用者在使用时便只需要调用工厂函数
即可,如此一来,即使更换了类名
,我们也只需要修改工厂函数
便可。
对于开头的场景,可以编写代码示例如下:
function popFactory(type, options) {
switch (type) {
case 'alert':
return new Alert(options)
case 'prompt':
return new Prompt(options)
case 'confirm':
return new Confirm(options)
}
}
如此,当我们要使用BetterAlert()
替换Alert()
时,只需修改return new Alert(options)
为return new BetterAlert(options)
除此之外,在场景中,我们会发现一个问题:
Alert、Prompt、Confirm之间会有很多共通点,如何抽象出这些共通点,使得代码更DRY呢?
我们便可使用另外一种方式:创建一个对象,然后对对象扩展属性和方法。这同样也是简单工厂模式
,示例如下:
function popFactory(type, options) {
const abstractPop = {}
abstractPop.title = options.title || '标题'
abstractPop.content = options.content || ''
abstractPop.show = function() {
// 显示弹框的处理逻辑
}
if (type === 'alert') {
// 处理alert不同的逻辑
}
if (type === 'prompt') {
// 处理prompt不同的逻辑
}
if (type === 'confirm') {
// 处理confirm不同的逻辑
}
return abstractPop
}
所以在JavaScript中,简单工厂模式
有两类创建对象的方法:
1)通过类
创建对象
2)通过创建一个新对象,然后包装增强其属性和方法
使用前者的好处在于,如果类
之间具有共用的方法,可以通过prototype
来实现共用,而后者每次调用创建的都是新的方法,所以不能实现方法的共用。但是两者各有各的好处,具体方式则应该依据具体的业务需求。