# 简单的工厂模式
工厂模式其实就是将创建对象的过程单独封装
总结一下:工厂模式的目的,就是为了实现无脑传参,就是为了爽!
文中举例: 是一个员工录入系统,其中共性的部分是 每个员工都有姓名、年龄、身份所以就可以给他们都封装成一个类
function User(name, age, career) {
this.name = name;
this.age = age;
this.career = career;
}
但是呢,老板说这个系统录入的信息也太简单了,程序员和产品经理之间的区别一个简单的 career
字段怎么能说得清?我要求这个系统具备给不同工种分配职责说明的功能。也就是说,要给每个工种的用户加上一个个性化的字段,来描述他们的工作内容。
所以员工的共性被拆离了,想要实现的话,可能就要封装出多个类,比如
function Coder(name, age) {
this.name = name;
this.age = age;
this.career = "coder";
this.work = ["写代码", "写系分", "修Bug"];
}
function ProductManager(name, age) {
this.name = name;
this.age = age;
this.career = "product manager";
this.work = ["订会议室", "写PRD", "催更"];
}
这样公司有多少个工种就会有多少类,所以这样明显是不可以的。回头想一下,所谓的work
其实也是每个员工都有的共性,只不过 work
字段需要随 career
字段取值的不同而改变,所以我们改造一下 User
类,然后把这个承载了共性的 User
类和个性化的逻辑判断写入同一个函数
function User(name , age, career, work) {
this.name = name
this.age = age
this.career = career
this.work = work
}
function Factory(name, age, career) {
let work
switch(career) {
case 'coder':
work = ['写代码','写系分', '修Bug']
break
case 'product manager':
work = ['订会议室', '写PRD', '催更']
break
case 'boss':
work = ['喝茶', '看报', '见客户']
case 'xxx':
// 其它工种的职责分配
...
return new User(name, age, career, work)
}
简单工厂解决的是多个类的问题。那么当复杂度从多个类共存上升到多个工厂共存时又该怎么处理呢?
# 抽象工厂
以上的方式封装 想要生产一台 FakeStar 手机时只需要这样做:
// 这是我的手机
const myPhone = new FakeStarFactory();
// 让它拥有操作系统
const myOS = myPhone.createOS();
// 让它拥有硬件
const myHardWare = myPhone.createHardWare();
// 启动操作系统(输出‘我会用安卓的方式去操作硬件’)
myOS.controlHardWare();
// 唤醒硬件(输出‘我会用高通的方式去运转’)
myHardWare.operateByOrder();
假如有一天,FakeStar 过气了,我们需要产出一款新机投入市场,这时候怎么办?我们是不是不需要对抽象工厂 MobilePhoneFactory
做任何修改,只需要拓展它的种类:
class newStarFactory extends MobilePhoneFactory {
createOS() {
// 操作系统实现代码
}
createHardWare() {
// 硬件实现代码
}
}
这样一来,对原有的系统不会造成任何潜在影响 所谓的“对拓展开放,对修改封闭”就这么圆满实现了。前面我们之所以要实现抽象产品类,也是同样的道理。
# 总结:
抽象工厂和简单工厂的异同
- 共同点:在于都尝试去分离一个系统中变与不变的部分
- 不同点:场景的复杂度。 简单工厂模式,处理的对象是类,共性容易抽离,逻辑本身比较简单。 抽象工厂本质上处理的其实也是类,但是是一帮非常棘手、繁杂的类这些类中不仅能划分出门派, 还能划分出等级,同时存在着千变万化的扩展可能性——这使得我们必须对共性作更特别的处理、使用抽象类去降低扩展的成本,同时需要对类的性质作划分。 于是有了这样的四个关键角色:
抽象工厂 (抽象类,它不能用于生成具体事例): 用于声明最终目标产品的共性。在一个系统里,抽象工厂可以有多个(大家可以想象我们的手机厂后来被一个更大的厂收购了,这个厂里除了手机抽象类,还有平板、游戏机抽象类等等),每一个抽象工厂对应的这一类的产品,被称为“产品族”。
具体工厂 (用于生成产品族里的一个具体的产品): 继承自抽象工厂、实现了抽象工厂里声明的那些方法,用于创建具体的产品的类。
抽象产品(抽象类,它不能被用于生成具体实例): 上面我们看到,具体工厂里实现的接口,会依赖一些类,这些类对应到各种各样的具体的细粒度产品(比如操作系统、硬件等),这些具体产品类的共性各自抽离,便对应到了各自的抽象产品类。
具体产品(用于生成产品族里的一个具体的产品所依赖的更细粒度的产品): 比如我们上文中具体的一种操作系统、或具体的一种硬件等。