Javascript设计模式 - 《工厂模式(创建型)》
概念
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但是允许子类决定实例化哪个类
工厂模式通过定义一个创建对象的接口,但将实际的实例化过程推迟到子类中去完成,从而使得一个类在创建对象时不需要关心具体的实现类
在工厂模式中,通常存在一个工厂类(Factory),它负责创建对象的实例
工厂类可以是简单工厂,也可以是工厂方法或抽象工厂的具体实现
工厂模式的核心思想是将对象的创建过程封装起来,使得客户端代码与具体的对象类解耦,从而提高系统的灵活性和可维护性
这种模式的优点在于,可以在不修改现有代码的情况下很容易地添加新的产品类,而且客户端代码与具体产品类解耦,使得系统更加灵活、可维护和可扩展
举个简单的例子,考虑一个文档编辑器
可以有不同类型的文档(如文本文档、图像文档等),而每种类型的文档可能需要不同的创建方式(如文本文档可以直接创建,而图像文档可能需要先加载图片)
使用工厂模式,可以将文档的创建过程封装到工厂类中,根据不同的类型来创建不同的文档对象,从而实现了文档的统一创建管理
实现条件
工厂模式适用于一些特定的情况,包括但不限于:
- 当一个系统需要独立于其产品的创建、组成和表示时,工厂模式能够帮助我们实现这一点
- 当要实例化的类在运行时才能确定时,例如,通过动态加载,工厂模式非常有用
- 当我们想要避免创建一个与产品类层次平行的工厂类层次时,工厂模式可以帮助我们减少类的数量
- 当一个类的实例只有几个不同状态组合中的一种时,使用工厂模式可能会比手动实例化更加方便,因为我们可以创建多个原型并根据需要克隆它们
优点
封装性
工厂模式可以隐藏创建对象的复杂逻辑,用户只需要知道他们可以从工厂获取对象,而无需关心对象的创建细节
扩展性
如果需要引入新的产品类,只需要扩展工厂类并在其中添加新的创建方法,这样不会影响已有的类代码
解耦
客户端代码和具体产品类解耦,客户端只依赖于产品的抽象类
这意味着客户端代码不需要更改就可以使用不同的产品
复用性
工厂类中的代码可以被多次复用,因为它们不依赖于具体的产品类
缺点
类的数量增多
每增加一个新的产品类型,都需要增加一个具体的产品类和一个与之对应的具体工厂类,这会使系统中类的总数增加,增加了系统的复杂度
系统的复杂性
随着产品变种的增加,相应的工厂类也会增加,系统的复杂性也随之增加,从而增加了理解和维护的难度
抽象性的问题
工厂模式的使用需要客户端依赖于工厂类的抽象编程,这对于一些需要理解具体类之间关系的场景可能不是很方便
实现方式
1 | /** |
这段代码定义了一个 Person
类和一个通用的工厂模式类 GenericFactoryPattern
,用于创建 Person
实例。下面是对这段代码的解释:
- Person 类:
- 这个类表示一个人,具有两个属性
name
和age
,分别代表人的名字和年龄 - 类中有一个方法
greet()
,用于向他人打招呼并介绍自己,它会在控制台输出一条打招呼的消息
- 这个类表示一个人,具有两个属性
- GenericFactoryPattern 类:
- 这个类是一个通用的工厂模式类,用于创建
Person
实例 - 类中有一个静态方法
createPerson(name, age)
,用于创建一个Person
实例。该方法接收两个参数,分别是人的名字和年龄 - 方法内部对输入参数进行合法性验证,确保
name
是字符串且age
是正数。如果参数不符合要求,则抛出相应的错误 - 如果参数验证通过,则使用输入参数创建并返回一个初始化后的
Person
实例
- 这个类是一个通用的工厂模式类,用于创建
场景
- JQuery的$()
- Vue异步组件
- Moment.js 中的
moment()