# 简单工厂
下面我们新建了 Coder 和 Manager 两个构造函数,用于创建不同的员工,但是一个公司不可能只有两种工种,如果针对每种岗位都新建一个构造函数的话,未免过于繁琐。
function Coder(name, age, career) {
this.name = name;
this.age = age;
this.career = career;
this.work = '写代码';
}
function Manager(name, age, career) {
this.name = name;
this.age = age;
this.career = career;
this.work = '见客户';
}
从上面可以看出,两个构造函数都有 name、age、career、work 属性,只是 work 的值根据不同的工种有不同而已。 下面我们把相同的逻辑封装到 User 中
function User(name, age, career, work) {
this.name = name;
this.age = age;
this.career = career;
this.work = work;
}
将不同的地方封装到 Factory 中
function Factory(name, age, career) {
let work;
switch(career) {
case 'coder':
work = '写代码';
break;
case 'manager':
work = '见客户';
break;
}
return new User(name, age, career);
}
这样我们在创建不同人员的时候只需要调用 Factory 方法就好了。
简单总结下:简单工厂模式是为了解决多个类的问题,将创建对象的过程单独封装。
# 抽象工厂
抽象工厂在前端的使用中并不多,只做了解即可。
class MobilePhoneFactory {
// 提供操作系统的接口
createOS(){
throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
}
// 提供硬件的接口
createHardWare(){
throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
}
}
// 具体工厂继承自抽象工厂
class FakeStarFactory extends MobilePhoneFactory {
createOS() {
// 提供安卓系统实例
return new AndroidOS()
}
createHardWare() {
// 提供高通硬件实例
return new QualcommHardWare()
}
}
系统类:
// 定义操作系统这类产品的抽象产品类
class OS {
controlHardWare() {
throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
}
}
// 定义具体操作系统的具体产品类
class AndroidOS extends OS {
controlHardWare() {
console.log('我会用安卓的方式去操作硬件')
}
}
class AppleOS extends OS {
controlHardWare() {
console.log('我会用🍎的方式去操作硬件')
}
}
硬件类:
// 定义手机硬件这类产品的抽象产品类
class HardWare {
// 手机硬件的共性方法,这里提取了“根据命令运转”这个共性
operateByOrder() {
throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
}
}
// 定义具体硬件的具体产品类
class QualcommHardWare extends HardWare {
operateByOrder() {
console.log('我会用高通的方式去运转')
}
}
class MiWare extends HardWare {
operateByOrder() {
console.log('我会用小米的方式去运转')
}
}
使用:
// 这是我的手机
const myPhone = new FakeStarFactory()
// 让它拥有操作系统
const myOS = myPhone.createOS()
// 让它拥有硬件
const myHardWare = myPhone.createHardWare()
// 启动操作系统(输出‘我会用安卓的方式去操作硬件’)
myOS.controlHardWare()
// 唤醒硬件(输出‘我会用高通的方式去运转’)
myHardWare.operateByOrder()
如需生产新的品牌手机,不需要对抽象工厂MobilePhoneFactory做任何修改,只需要拓展它的种类,这样不会对原有的系统不会造成任何潜在影响。
class newStarFactory extends MobilePhoneFactory {
createOS() {
// 操作系统实现代码
}
createHardWare() {
// 硬件实现代码
}
}
如果你使用过 TS, 有点像 TS 中的 interface。
- 抽象工厂(抽象类,它不能被用于生成具体实例): 用于声明最终目标产品的共性。在一个系统里,抽象工厂可以有多个(大家可以想象我们的手机厂后来被一个更大的厂收购了,这个厂里除了手机抽象类,还有平板、游戏机抽象类等等),每一个抽象工厂对应的这一类的产品,被称为“产品族”。
- 具体工厂(用于生成产品族里的一个具体的产品): 继承自抽象工厂、实现了抽象工厂里声明的那些方法,用于创建具体的产品的类。
- 抽象产品(抽象类,它不能被用于生成具体实例): 上面我们看到,具体工厂里实现的接口,会依赖一些类,这些类对应到各种各样的具体的细粒度产品(比如操作系统、硬件等),这些具体产品类的共性各自抽离,便对应到了各自的抽象产品类。
- 具体产品(用于生成产品族里的一个具体的产品所依赖的更细粒度的产品): 比如我们上文中具体的一种操作系统、或具体的一种硬件等。
抽象工厂模式的定义,是围绕一个超级工厂创建其他工厂。