什么是工作模式?
工厂是用来干嘛的? 毫无疑问,工厂就是用来生产东西的
对于 js 的工厂模式来说,就是为了创建对象用的 上一节我们了解了单例模式,单例模式的特点是全局唯一 那么工厂模式就是为了生产大量产品用的
在大量创建对象的时候,会用到工厂模式
工厂模式的分类
一 简单工厂模式
生成少量的产品用到这种方法,很简单,就是在类的里面,通过 if 判断,不同条件,new 一个不同的对象返回就行了
我们以生成手机为例,如下代码
//手机的基类
class Phone {
call(){
console.log('我用手机打电话')
}
}
//小米手机
class XiaoMiPhone extends Phone {
call(){
console.log('我用小米手机打电话')
}
}
//苹果手机
class ApplePhone extends Phone {
call(){
console.log('我用苹果手机打电话')
}
}
我们来创建一个工厂类,专门生成手机的工厂类,代码如下
// 有了上面的产品类定义后,我们如果生成这些手机怎么做?
// 当然需要建一个生成手机的工厂类了
class PhoneFactory{
//根据不同的类型,创建不同的手机,也就是所谓的工厂生成的产品
produce(type){
if(type === 'xiaomi'){
return new XiaoMiPhone()
} else if (type == 'apple') {
return new ApplePhone()
} else {
return new Phone()
}
}
}
可以看到我们建了一个 PhoneFactory
类,从字面意思就知道,是生成手机的工厂
这就是简单的工厂模式
二 工厂方法模式
为什么叫工厂方法模式,关键在于“方法
”,因为工厂方法模式中,工厂类中有许多的方法用来生产不同的手机,不同于简单工作模式(工厂中只有一个生产方法),工厂方法模式中,工厂类中有许多的方法
用来生产不同的产品的,工厂类的代码如下
// 和上面简单工厂模式不一样的是,工厂方法模式中,工厂类中有很多的方法创建不同的手机
// 而上面的简单工厂模式只有一个方法,在方法里面通过不同的 if 条件来创建不同的手机
// 重点在于 方法 这个词上
class PhoneFactory{
//专门生产小米手机的方法
produceXiaoMiPhone(){
return new XiaoMiPhone()
}
//专门生产苹果手机的方法
produceApplePhone(){
return new ApplePhone()
}
}
工厂类中有很多专用的方法来生产产品,怎么用呢?如下
//创建一个工厂对象
let factory = new PhoneFactory()
//调用工厂对象创建不同的产品
let xiaomiPhone = factory.produceXiaoMiPhone()
let applePhone = factory.produceApplePhone()
//调用
xiaomiPhone.call()
applePhone.call()
上面的代码其实还可以再优化的,上面的可以优化的点在于:每次创建不同产品的时候,必须先要创建一个工厂对象
我们是不是可以优化一下,把生产不同产品的方法,设置为静态的,这样的话,我们生产不同的手机的话,就不需要再先创建一个工厂对象了
代码优化如下
//工厂类
class PhoneFactory{
//专门生产小米手机的方法
//设置为 static
static produceXiaoMiPhone(){
return new XiaoMiPhone()
}
//专门生产苹果手机的方法
//设置为 static
static produceApplePhone(){
return new ApplePhone()
}
}
//直接调用工厂的静态方法来生产不同的手机
let xiaomiPhone = PhoneFactory.produceXiaoMiPhone()
let applePhone = PhoneFactory.produceApplePhone()
//调用
xiaomiPhone.call()
applePhone.call()
经过上面的优化,就不用每次都先创建工厂对象了,这样我们就省了一步 使代码更简洁了
抽象工厂模式
学习了上面2种工厂模式之后,会不会有个疑问呢? 现在生活中,一个工厂也许只生产一种手机,假如苹果的工厂,只生成苹果手机,不生成小米手机,同样的,小米工厂只生成小米手机,不生成苹果手机
那么这种情况下怎么办呢?上面2种模式就不再适合了
这个时候就需要我们的抽象工厂模式了
什么是抽象工厂模式? 说白了,就是每个工厂只生产一种产品 比如有一个工厂叫 AppleFactory, 只生成苹果手机 比如有一个工厂叫 XiaoMiFactory,只生成小米手机
//只生产小米手机的工厂
class XiaoMiFactory {
produce(){
return new XiaoMiPhone()
}
}
function producePhone(){
//苹果工厂对象 ,生产苹果手机
let appleFactory = new AppleFactory()
let applePhone = appleFactory.produce()
//小米工厂对象,生产小米手机
let xiaoMiFactory = new XiaoMiFactory()
let xiaomiPhone = xiaoMiFactory.produce()
}
producePhone()
通过工厂模式,我们来解释一下设计模式的六大原则之 对扩展开放,对修改关闭
什么意思? 对修改关闭,就是我现在要新加一个生产华为手机的需求
对于简单工厂:我们只需要在原有的代码上添加一句
if (type === 'huawei') { }
就行了对于工厂方法:我们只需要在工厂类中添加一句
produceHuaweiPhone(){ }
就行了
上面2种方法,都需要在原有的代码基础上进行修改
,才能实现,这样是不是很容易出错,比如程序员不小心写成了 if (type === 'huaweiiii') { }
把huawei
单词拼错了,写成了huaweiiii
,那用的人是不是要抓狂。
添加一个功能,需要修改原来的代码才能实现,这种就容易出错 对修改关闭的意思就是:添加一个功能,不需要修改原来的代码,也能实现
不修改原来的代码怎么实现呢?对了,就是抽象工厂方法,直接新建一个文件,里面添加一个工厂类就行了,没有修改原来的代码,还扩展了功能,还没有修改原来的代码 这就是对扩展开放,这样注不容易出错
因为js是弱类型语言,如果用java语言更容易演示这个原则,有兴趣的话大家可以看看java的实现,不过都差不多