1 创建型-工厂模式
1.1 简单工厂模式
其实就是将创建对象的过程单独封装 ,同时它的应用场景也非常容易识别:有构造函数的地方,我们就应该想到简单工厂;在写了大量构造函数、调用了大量的 new、自觉非常不爽的情况下,我们就应该思考是不是可以掏出工厂模式重构我们的代码了
// 给不同工种分配职责说明
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 = ['喝茶', '看报', '见客户']
break;
}
}
return new User(name, age, career, work)
}
const wang = new Factory('wang', 50, 'boss');
const sun = new Factory('sun', 25, 'coder');
const li = new Factory('li', 30, 'product-manager');
console.log(wang)
console.log(sun)
console.log(li)
1.2 抽象工厂模式
// 定义操作系统这类产品的抽象产品类
class OS {
constructor() {
if (new.target === OS) {
throw new Error('不能实例化抽象类');
}
}
}
// 定义具体操作系统的具体产品类
class AndroidOS extends OS {
constructor() {
super();
}
controlHardware() {
console.log('我会用安卓的方式去操作硬件');
}
}
class AppleOS extends OS {
constructor() {
super();
}
controlHardware() {
console.log('我会用苹果的方式去操作硬件');
}
}
// 定义手机硬件这类产品的抽象产品类
class Hardware {
constructor() {
if (new.target === Hardware) {
throw new Error('不能实例化抽象类');
}
}
// 手机硬件的共性方法,这里提取了“根据命令运转”这个共性
operateByOrder() {
throw new Error('抽象产品方法不允许直接调用,你需要将我重写!');
}
}
// 定义具体硬件的具体产品类
class QualcommHardware extends Hardware {
constructor() {
super();
}
operateByOrder() {
console.log('我会用高通的方式去运转')
}
}
class MiWare extends Hardware {
constructor() {
super();
}
operateByOrder() {
console.log('我会用小米的方式去运转')
}
}
class MobilePhoneFactory {
// 提供操作系统的接口
createOS() {
throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
}
// 提供硬件的接口
createHardware() {
throw new Error("抽象工厂方法不允许直接调用,你需要将我重写!");
}
}
// 具体工厂继承自抽象工厂
class FakeStarFactory extends MobilePhoneFactory {
constructor() {
super()
}
createOS() {
// 提供安卓系统实例
return new AndroidOS()
}
createHardware() {
// 提供高通硬件实例
return new QualcommHardware()
}
}
// 这是我的手机
const myPhone = new FakeStarFactory()
// 让它拥有操作系统
const myOS = myPhone.createOS()
// 让它拥有硬件
const myHardWare = myPhone.createHardware()
// 启动操作系统(输出‘我会用安卓的方式去操作硬件’)
myOS.controlHardware()
// 唤醒硬件(输出‘我会用高通的方式去运转’)
myHardWare.operateByOrder()
抽象工厂和简单工厂的思路,思考一下:它们之间有哪些异同?
- 它们的共同点,在于都尝试去分离一个系统中变与不变的部分 。
- 它们的不同在于场景的复杂度 。
在简单工厂的使用场景里,处理的对象是类,并且是一些非常好对付的类——它们的共性容易抽离,同时因为逻辑本身比较简单,故而不苛求代码可扩展性。抽象工厂本质上处理的其实也是类,但是是一帮非常棘手、繁杂的类,这些类中不仅能划分出门派,还能划分出等级,同时存在着千变万化的扩展可能性——这使得我们必须对共性 作更特别的处理、使用抽象类去降低扩展的成本,同时需要对类的性质作划分
