什么是工厂模式?
工厂模式(Factory Pattern)是创建型设计模式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来创建对象。
简单工厂模式
假如有一个屏幕生产工厂,生产各类屏幕。每类屏幕都是一个类,如下,我们通过屏幕工厂类提供的 createScreen
统一接口来创建屏幕对象。这便是一个简单工厂模式的应用。
// 屏幕工厂类
class ScreenFactory {
createScreen(type) {
if (type === "hd") {
return new HDScreen()
} else if(type === 'normal') {
return new NormalScreen()
} else {
return null
}
}
}
// 高清屏幕类
class HDScreen {
say() {
console.log('I am HDScreen!')
}
}
// 普通屏幕类
class NormalScreen {
say() {
console.log('I am NormalScreen!')
}
}
// 创建屏幕工厂实例
var screenFactory = new ScreenFactory()
// 用统一接口 createScreen 分别创建高清屏幕和普通屏幕
var hdScreen = screenFactory.createScreen('hd')
var normalScreen = screenFactory.createScreen('normal')
hdScreen.say() // => 'I am HDScreen!'
normalScreen.say() // => 'I am NormalScreen!'
通过简单工厂模式,我们对创建对象的过程做了一层封装,从而达到解耦的目的。
这样做的优势就是,有一天某类屏幕子类名变了(比如 HDScreen 类名换成 SuperScreen),初始化的参数更新了,或者任何实现细节改变了,用户都不需要关心,还是可以依旧用 createScreen
接口创建对象。反过来,如果不是用工厂模式,而是用原始的 new 操作创建对象,那么用户就需要考虑这些修改需不需要对旧代码进行更新。
因此,避免随意通过 new 来创建对象,对系统的后期维护会带来很大便利。
工厂模式
虽然简单工厂模式已经达到了解耦的目的,但是每次需要添加新零件类的时候,都需要对零件工厂类进行对应的修改(加个 if 判断或者 switch 条件之类)。这样就违背了开闭原则。
所以我们希望一个工厂类就返回一个实例。即对每个屏幕类也进行工厂模式的封装。
如下:
// 高清屏幕工厂
class HDScreenFactory {
createScreen() {
return new HDScreen()
}
}
// 普通屏幕工厂
class NormalScreenFactory {
createScreen() {
return new NormalScreen()
}
}
// 高清屏幕类
class HDScreen {
say() {
console.log('I am HDScreen!')
}
}
// 普通屏幕类
class NormalScreen {
say() {
console.log('I am NormalScreen!')
}
}
// 创建高清屏幕工厂实例
var hdScreenFactory = new HDScreenFactory()
// 用统一接口 createScreen 分别创建高清屏幕
var hdScreen = hdScreenFactory.createScreen()
hdScreen.say() // => 'I am HDScreen!'
这样就不需要通过参数的形式区分该实例化哪个类,同时当需要再添加一个 UltraHDSreen 超高清屏幕类型时,我们就不需要对原有代码进行改动。
抽象工厂模式
抽象工厂模式可以理解成工厂的工厂,封装一组具有共同目标的单一工厂。
对于手机工厂,不仅需要生产屏幕,还需要生产摄像头等。这里添加了一个旗舰手机工厂,
在创建屏幕和摄像头时,我们直接用旗舰手机工厂去创建。
当然如果是其他类型的手机,可以用其对应的手机工厂创建,实例中没有列出。
在抽象工厂模式下,产品和零件在一个工厂中组合为一个整体,更加抽象。与此同时也增加了系统的复杂度。
// 手机工厂
class PhoneFactory {
createScreen() {}
createCamera() {}
}
// 旗舰手机工厂
class FlagShipPhoneFactory {
createScreen() {
return new HDScreen()
}
createCamera() {
return new HDCamera()
}
}
// 高清屏幕工厂
class HDScreenFactory {
createScreen() {
return new HDScreen()
}
}
// 普通屏幕工厂
class NormalScreenFactory {
createScreen() {
return new NormalScreen()
}
}
// 高清摄像头工厂
class HDCameraFactory {
createCamera() {
return new HDCamera()
}
}
// 高清摄像头类
class HDCamera {
say() {
console.log('I am HDCamera!')
}
}
// 高清屏幕类
class HDScreen {
say() {
console.log('I am HDScreen!')
}
}
// 普通屏幕类
class NormalScreen {
say() {
console.log('I am NormalScreen!')
}
}
// 创建旗舰手机工厂实例
var phone = new FlagShipPhoneFactory()
// 用统一接口分别创建旗舰手机的屏幕和摄像头
var screen = phone.createScreen()
var camera = phone.createCamera()
screen.say() // => 'I am HDScreen!'
camera.say() // => 'I am HDCamera!'
以上便是工厂模式的全部内容。