前端设计模式:工厂模式(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 )
️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀
前端设计模式:工厂模式(Factory)的更多相关文章
- 设计模式 - 工厂模式(factory pattern) 具体解释
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/27081511 工厂模式(factory pa ...
- 大话设计模式--工厂模式 factory -- C++实现实例
实现<大话设计模式>的C++版本... 1. 工厂模式 使用的范围是 同一个基类,下面很多子类. (1)这里很容易出现的一个问题n多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就 ...
- 设计模式--工厂模式Factory(创建型)
工厂模式属于创建型模式,分为三类,简单工厂模式.工厂方法模式.抽象工厂模式. 一.简单工厂模式 在工厂中做判断,根据产品类型从而创造相应的产品,当增加新产品时需要修改工厂类. 例如: enum CTY ...
- [设计模式]工厂模式factory
参考:http://wxg6203.iteye.com/blog/740229 简单工厂模式(simple factory)是类的创建模式,又叫静态工厂方法(static factory method ...
- 23种设计模式--工厂模式-Factory Pattern
一.工厂模式的介绍 工厂模式让我们相到的就是工厂,那么生活中的工厂是生产产品的,在代码中的工厂是生产实例的,在直白一点就是生产实例的类,代码中我们常用new关键字,那么这个new出来的实例 ...
- 设计模式——工厂模式(Factory Method)
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪个类.工厂方法使一个类的实例化延迟到其子类. UML图: 运算基类: package com.cnblog.clarck; /** * 数据 ...
- 设计模式(一)工厂模式Factory(创建型)
设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.可是在一些情况下, new操作符直接生成对象会带来一些问题. ...
- 设计模式(一)工厂模式Factory(创建类型)
设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.可是在一些情况下, new操作符直接生成对象会带来一些问题. ...
- 设计模式(一)工厂模式Factory(创建型)(转)
原文链接:http://blog.csdn.net/hguisu/article/details/7505909 设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符 ...
- C# 设计模式-工厂模式(Factory)
1.工厂模式 factory从若干个可能类创建对象. 例如:如果创建一个通信类接口,并有多种实现方式,可以使用factory创建一个实现该接口的对象,factory可以根据我们的选择,来创建适合的对象 ...
随机推荐
- CoFiltering:BestPracticesandTechniquesinTextGeneration
目录 Co-Filtering: Best Practices and Techniques in Text Generation Introduction: Text generation has ...
- Enhancingdecisiontreeswithtransferlearningforsentimenta
目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...
- SpringBoot RabbitMQ 实战解决项目中实践
1 基础预览 1.1 环境准备 Springboot 1.5.6.RELEAS Springcloud Dalston.SR2 1.2 交换机类型 交换机是用来发送消息的AMQP实体.交换机拿到一个消 ...
- 【promptulate专栏】ChatGPT框架——两行代码构建一个强大的论文总结助手
本文节选自笔者博客:https://www.blog.zeeland.cn/archives/019hasaa 前言 如果你经常阅读论文,那么你肯定会遇到以下几个问题: 论文晦涩难懂看不明白怎么办? ...
- .NET表达式树
IQueryable/IQueryable 和表达式树 IQueryable有两个组件 Expression:当前查询的组件的与语言和数据源无关的表示形式,以表达式树的形式表示. Provider:L ...
- 国内可用的GPT4镜像站
我做了个镜像站,GPT4的费用目前太贵了. 虽然做了个低价的月费,但基本上亏本在做,接口的实际费用高出太多. 运行了1个月,每天有几十人在用吧. 有兴趣的可以收藏一下 GPT4的验明正身的问题&quo ...
- 即构推出低延迟直播产品L3,可将直播延迟降到1s
近日,全球云通讯服务提供商ZEGO即构科技推出低延迟直播产品Low-Latency Live,简称L3.这款产品对传统CDN直播中"延迟较大.弱网抗性差.观众端内容不同步"等问题进 ...
- 通配符SSL证书自动续签自动部署方案
最开始接触 https 的时候一直是使用的 阿里云和腾讯云的免费 SSL证书,免费的SSL证书用了几年后,慢慢的部署https证书的项目越来越多,时间久了发现每个网站都需要一个 SSL证书,每个SSL ...
- 层叠样式表(CSS)2(环境:MyEclipse 10)
二.选择器 注:在head里面写选择器的内容.环境一直不变,所有HTML和css都是这个MyEclipse 10 1.基本选择器(每个选择器新建一个HTML网页测试学习) 元素选择器:按节点名称匹配元 ...
- Django: 获取头信息
如何获取请求头信息 使用如下函数request.META.get("HTTP_请求头函数"),需要注意的是,请求头变量需要全部大写. 其他注意事项如下所示: 如果headerkey ...