前端设计模式:工厂模式(Factory)
00、基础概念
🚩工厂模式封装了对象的创建
new()
,将消费者(使用)和生产者(实现)解耦。
工厂是干什么的?工厂是生产标准规格的商品的地方,建好工厂,投入原料(参数),产出特定规格的产品。so,工厂模式就是把对象的创建 —— new()
封装起来,在工厂里实现对象的创建(商品的生产)。这样做的好处是用来解耦,解耦对象的消费(使用)和创建(实现),面向抽象编程(这个用到TS中的接口类型)。
✅使用场景:
- Vue中的
createElement('h'); createElement('div')
创建虚拟Dom;vue-router 中的路由基于模式mode
创建不同的路由对象。 - 多个同类对象的创建,创建过程复杂,而使用者不用关注创建、实现过程,只管拿到实例来使用。就像我们日常到超市购买商品,只管选择使用,不用关注商品是怎么生产的。
生产实例(商品)的工厂可以是小作坊,只生产少量简单的商品,也可以是大型的复杂工厂,因此基于场景复杂程度又有多个工厂模式:
类别 | 说明 |
---|---|
简单工厂(Simple Factory) | 小作坊,适用于少量对象的创建,集中式管理,使用简单、扩展不便 |
工厂方法(Factory Method) | 正规小工厂,每种产品一个独立工厂,偏平化扩展 |
抽象工厂(Abstract Factory) | 集团化大厂,产品种类、层级众多,需要多层级的工厂来管理,代码也稍复杂 |
实际掌握简单工厂就差不多了,工厂方法、抽象工厂了解下即可。
01、简单工厂(Simple Factory)
简单工厂模式,也称为静态工厂模式(Static Factory Method),由一个(静态)类统一管理对象的创建,,根据一个简单参数创建不同的示例对象。针对少量的、简单的场景,在工厂中统一实现所有商品的创建。如下示例,手机工厂提供多型号手机的创建,传入手机型号参数即可。
示例代码:
let HuaweiPhone = class { name = '华为' } let XiaomiPhone = class { name = '小米' } // 手机生产工厂 class PhoneFactory { static create(type) { switch (type) { case 'huawei': return new HuaweiPhone() case 'xiaomi': return new XiaomiPhone() default: throw new Error(`不支持生产型号为${type}的设备`) } } } // 使用,调用工厂方法创建对象实例 let p1 = PhoneFactory.create('xiaomi') let p2 = PhoneFactory.create('huawei') console.log({ p1, p2 })
上面版本代码中,如果扩充其他型号,则需要修改工厂的代码,不利于扩展,可以稍微改进下,支持动态新增创建对象实例的方法。
// 手机生产工厂 class PhoneFactory { // 实例对象创建器Map #constructors = new Map() constructor() { this.#constructors.set('huawei', () => new HuaweiPhone()) this.#constructors.set('xiaomi', () => new XiaomiPhone()) } // 可扩展型号 add(type, func) { this.#constructors.set(type, func) } // 生产商品 create(type) { const func = this.#constructors.get(type) if (func) { return func.call() } throw new Error(`不支持生产型号为${type}的设备`) } } const phoneFactory = new PhoneFactory() // 添加苹果型号 let IPhone = class { name = '苹果' } phoneFactory.add('iphone', () => new IPhone()) // 使用,调用工厂方法创建对象实例 let p1 = phoneFactory.create('iphone') let p2 = phoneFactory.create('huawei')
02、工厂方法(Factory Method)
简单工厂是小作坊,产量有限,如果生产的型号很多,在一个地方管理所有的new()
操作,负担很大,风险也很大。工厂方法(也叫工厂模式)就是为每一个产品建立单独的工厂,一个工厂只生产一类商品,这样就可以灵活扩展,相互不影响了。
代码示例:
let HuaweiPhone = class { name = '华为' } let XiaomiPhone = class { name = '小米' } // 没什么用的工厂基类(JS中可以不要),用来抽象工厂接口 let IFactory = class { creat() { } } // 华为手机工厂 class HuaweiFactory extends IFactory { creat() { return new HuaweiPhone() } } // 小米手机工厂 class XiaomiFactory extends IFactory { creat() { return new XiaomiPhone() } } // 使用 const huaweiFactory = new HuaweiFactory() let p1 = huaweiFactory.creat() let p2 = huaweiFactory.creat()
在Java、C#语言中都会用接口进行抽象、约束,面向抽象编程,实现起来会比较清晰。JavaScript中就没法抽象约束了,比较随意,只能靠TypeScript了。
03、抽象工厂(Abstract Factory)
如果说简单工厂是小作坊,工厂方法就是小工厂,那抽象工厂就是大型集团了,下属多个产业链、多个工厂。
抽象工厂可以看做是简单工厂+工厂方法的结合升级,增加了产品族的概念。还是用电子产品生产来举例,比如一个大型电子产品工厂,有多个品牌产品,如华为、小米,每个品牌的电子产品形成一个产品族,包含多个产品,如手机、平板、电视等等,不同品牌的产品也是不同的。因此一个产品工厂(如华为工厂)就会有多条生产线,生产多个产品(手机、平板、电视)。
🚩基本结构:抽象工厂类+具体工厂类,抽象产品类+具体产品类组合。JS中没有没有抽象类、接口的概念,只能示意一下(或者TS),抽象工厂简单了解即可,掌握上面的简单工厂、工厂方法就差不多了。
示例代码:
// 模拟手机抽象类 let IPhone = class { name = '手机' } // 手机产品 let HuaweiPhone = class extends IPhone { name = '华为' + this.name } let XiaomiPhone = class extends IPhone { name = '小米' + this.name } // 模拟电视抽象类 let ITV = class { name = '电视' } // 电视产品 let HuaweiTV = class extends ITV { name = '华为' + this.name } let XiaomiTV = class extends ITV { name = '小米' + this.name } // 模拟抽象工厂,含两个抽象方法,生产手机、电视 let AbstractFactory = class { createPhone() { }; createTV() { } } // 具体工厂:华为工厂 class HuaweiFactory extends AbstractFactory { createPhone() { return new HuaweiPhone() } createTV() { return new HuaweiTV() } } // 具体工厂:小米工厂 class XiaomiFactory extends AbstractFactory { createPhone() { return new XiaomiPhone() } createTV() { return new XiaomiTV() } } // 使用 let xiaomiFactory = new XiaomiFactory() let m1 = xiaomiFactory.createPhone(); let m2 = xiaomiFactory.createTV(); console.log(m1, m2) // XiaomiPhone {name: '小米手机'} XiaomiTV {name: '小米电视'}
参考资料
- 《Head First 设计模式 中文版》
- JavaScript Patterns
- 简单工厂模式( Simple Factory Pattern )
©️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤