TypeScript 设计模式:五大创建型模式
设计模式是面向对象编程中总结出的可复用设计方案,而创建型模式是日常开发里使用频率极高的一类模式。它的核心作用是封装对象创建逻辑、隔离对象实例化细节,让业务代码和对象创建过程解耦,同时保证代码灵活、易扩展、易维护。
经典创建型模式一共包含 5 种:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。本文结合 TypeScript 语言,从核心思想、适用场景、优缺点、完整代码实现、代码解析逐一详解,所有代码严格遵循统一编码格式规范。
一、单例模式
1. 核心思想
确保一个类在整个应用全局中仅有一个实例,并且对外提供一个统一、全局的访问入口。无论代码中多少次尝试创建该类对象,最终得到的都是同一个实例。
2. 适用场景
- 全局配置类、全局状态管理、全局工具类;
- 资源独享场景:数据库连接池、网络请求连接池、文件读写对象;
- 弹窗、全局弹窗控制器、日志统一输出类等只需要一份实例的组件。
3. 优缺点
- 优点:全局资源统一管控、减少内存开销、避免重复创建对象;
- 缺点:单例类职责过重,不符合单一职责原则;在多模块、多并发场景下容易引发线程 / 执行顺序问题;扩展难度较高。
4. 代码实现(懒汉式单例)
const MAX_INSTANCE_COUNT = 1;
class Global_Config {
// 私有静态属性,保存唯一实例
private static instance: Global_Config | null = null;
// 私有构造方法,禁止外部 new 实例
private constructor() {
}
// 对外统一获取实例的静态方法
public static Get_Instance(): Global_Config {
// 常量放左侧,变量放右侧
if (null == Global_Config.instance) {
Global_Config.instance = new Global_Config();
}
return Global_Config.instance;
}
// 业务方法
public Set_Config(key: string, value: string): void {
console.log(`配置项 ${key} 已设置为 ${value}`);
}
public Print_All_Config(): void {
console.log("打印全部全局配置信息");
}
}
// 测试调用
let config_1 = Global_Config.Get_Instance();
let config_2 = Global_Config.Get_Instance();
if (config_1 == config_2) {
console.log("两次获取的是同一个单例实例");
}
config_1.Set_Config("app_name", "ts_demo");
config_2.Print_All_Config();
5. 代码说明
- 常量
MAX_INSTANCE_COUNT全大写 + 下划线命名,符合规范; - 构造函数使用
private修饰,彻底阻止外部通过new创建对象; if判断将常量null写在左侧,变量在右侧;所有运算符前后均添加空格;- 函数命名采用首字母大写 + 下划线分隔风格;
- 采用懒加载:第一次调用
Get_Instance时才创建实例,节省初始化资源。
二、工厂方法模式
1. 核心思想
定义一个创建产品的抽象工厂接口,将具体对象的创建工作交给工厂子类完成。父类只定义创建规范,不关心具体创建哪一个对象,完全遵循开闭原则。
简单理解:一个工厂对应一种产品,新增产品时只需要新增对应的工厂类,无需修改原有代码。
2. 适用场景
- 产品种类固定、但需要持续扩展产品的场景;
- 对象创建逻辑复杂,需要统一封装创建过程;
- 客户端只依赖抽象,不依赖具体实现类的架构设计。
3. 优缺点
- 优点:符合开闭原则、代码解耦、分工明确;
- 缺点:每新增一个产品,就必须新增一个对应的工厂类,会造成类文件数量增多。
4. 代码实现
// 抽象产品接口:定义产品统一行为
interface Electronic_Product {
Show_Product_Info(): void;
}
// 具体产品 1:手机
class Smart_Phone implements Electronic_Product {
public Show_Product_Info(): void {
console.log("产品:智能手机 | 支持通话、上网、拍照");
}
}
// 具体产品 2:平板
class Tablet_Pad implements Electronic_Product {
public Show_Product_Info(): void {
console.log("产品:平板电脑 | 支持影音、办公、手写");
}
}
// 抽象工厂接口:定义统一创建产品的规范
interface Product_Factory {
Create_Product(): Electronic_Product;
}
// 手机工厂:专门生产手机
class Phone_Factory implements Product_Factory {
public Create_Product(): Electronic_Product {
return new Smart_Phone();
}
}
// 平板工厂:专门生产平板
class Pad_Factory implements Product_Factory {
public Create_Product(): Electronic_Product {
return new Tablet_Pad();
}
}
// 测试调用
let phone_factory: Product_Factory = new Phone_Factory();
let phone = phone_factory.Create_Product();
phone.Show_Product_Info();
let pad_factory: Product_Factory = new Pad_Factory();
let pad = pad_factory.Create_Product();
pad.Show_Product_Info();
5. 代码说明
- 所有
interface、class、方法命名统一使用大写下划线格式; if/for等语句本文无使用,所有代码块{}紧跟在上一行末尾,}独占一行;- 赋值运算符、关系运算符前后均保留空格,逗号后添加空格;
- 客户端仅依赖抽象接口
Product_Factory和Electronic_Product,和具体实现解耦。
三、抽象工厂模式
1. 核心思想
抽象工厂模式是工厂方法模式的升级版。工厂方法一个工厂只生产单一产品,而抽象工厂一个工厂可以生产一组相互关联、相互依赖的产品族。
简单理解:按产品线 / 产品系列划分工厂,每个工厂负责一整套配套组件。
2. 适用场景
- 系统存在多个产品族,且产品之间必须配套使用;
- 需要保证同一产品族的产品始终在一起使用;
- 产品等级固定,但产品系列需要频繁扩展。
3. 优缺点
- 优点:保证产品配套、隔离产品族、扩展性强;
- 缺点:如果需要新增产品等级,整个工厂体系都需要大幅修改,违背开闭原则。
4. 代码实现
// 产品等级 1:屏幕接口
interface Device_Screen {
Show_Screen_Feature(): void;
}
// 产品等级 2:电池接口
interface Device_Battery {
Show_Battery_Feature(): void;
}
// 手机产品族 - 具体屏幕
class Phone_Screen implements Device_Screen {
public Show_Screen_Feature(): void {
console.log("手机屏幕:6.5英寸高清屏");
}
}
// 手机产品族 - 具体电池
class Phone_Battery implements Device_Battery {
public Show_Battery_Feature(): void {
console.log("手机电池:4500mAh 大容量电池");
}
}
// 平板产品族 - 具体屏幕
class Pad_Screen implements Device_Screen {
public Show_Screen_Feature(): void {
console.log("平板屏幕:10.9英寸全面屏");
}
}
// 平板产品族 - 具体电池
class Pad_Battery implements Device_Battery {
public Show_Battery_Feature(): void {
console.log("平板电池:8000mAh 长续航电池");
}
}
// 抽象工厂:定义生产整套组件的规范
interface Device_Abstract_Factory {
Create_Screen(): Device_Screen;
Create_Battery(): Device_Battery;
}
// 手机工厂:生产手机整套组件
class Phone_Component_Factory implements Device_Abstract_Factory {
public Create_Screen(): Device_Screen {
return new Phone_Screen();
}
public Create_Battery(): Device_Battery {
return new Phone_Battery();
}
}
// 平板工厂:生产平板整套组件
class Pad_Component_Factory implements Device_Abstract_Factory {
public Create_Screen(): Device_Screen {
return new Pad_Screen();
}
public Create_Battery(): Device_Battery {
return new Pad_Battery();
}
}
// 测试调用
let phone_factory: Device_Abstract_Factory = new Phone_Component_Factory();
let phone_screen = phone_factory.Create_Screen();
let phone_battery = phone_factory.Create_Battery();
phone_screen.Show_Screen_Feature();
phone_battery.Show_Battery_Feature();
let pad_factory: Device_Abstract_Factory = new Pad_Component_Factory();
let pad_screen = pad_factory.Create_Screen();
let pad_battery = pad_factory.Create_Battery();
pad_screen.Show_Screen_Feature();
pad_battery.Show_Battery_Feature();
5. 代码说明
- 一套工厂同时创建多个关联对象,保证组件配套使用;
- 代码缩进统一为 4 个空格,大括号格式严格遵循规范;
- 运算符、逗号、分号前后空格统一,整体格式规整。
四、建造者模式(Builder 模式)
1. 核心思想
将复杂对象的构建过程与对象本身分离,使用分步构建的方式创建对象。可以用同样的构建流程,创建出不同属性、不同形态的复杂对象。
当一个类拥有大量属性、构造函数参数过多、存在大量可选参数时,优先使用建造者模式。
2. 适用场景
- 对象属性多,且大部分属性为可选参数;
- 需要创建不同配置、不同组合的复杂对象;
- 不希望使用重载构造函数来实现多参数实例化。
3. 优缺点
- 优点:参数组合灵活、代码可读性高、避免超长构造函数;
- 缺点:会额外增加建造者类,增加代码体量。
4. 代码实现
// 定义常量:默认参数
const DEFAULT_USER_AGE = 18;
const DEFAULT_USER_GENDER = "unknown";
// 目标复杂对象:用户类
class System_User {
public user_name: string;
public user_age: number;
public user_gender: string;
public user_role: string;
constructor(name: string, age: number, gender: string, role: string) {
this.user_name = name;
this.user_age = age;
this.user_gender = gender;
this.user_role = role;
}
public Show_User_Info(): void {
console.log(`用户名:${this.user_name},年龄:${this.user_age},性别:${this.user_gender},角色:${this.user_role}`);
}
}
// 建造者类:分步构建 User 对象
class User_Builder {
private name: string = "";
private age: number = DEFAULT_USER_AGE;
private gender: string = DEFAULT_USER_GENDER;
private role: string = "guest";
public Set_User_Name(name: string): User_Builder {
this.name = name;
return this;
}
public Set_User_Age(age: number): User_Builder {
this.age = age;
return this;
}
public Set_User_Gender(gender: string): User_Builder {
this.gender = gender;
return this;
}
public Set_User_Role(role: string): User_Builder {
this.role = role;
return this;
}
// 最终构建并返回完整对象
public Build_User(): System_User {
return new System_User(this.name, this.age, this.gender, this.role);
}
}
// 测试调用
let user_builder = new User_Builder();
// 链式调用,自由选择参数组合
let admin_user = user_builder
.Set_User_Name("admin")
.Set_User_Age(26)
.Set_User_Gender("male")
.Set_User_Role("administrator")
.Build_User();
admin_user.Show_User_Info();
// 部分参数使用默认值
let guest_user = new User_Builder()
.Set_User_Name("visitor")
.Build_User();
guest_user.Show_User_Info();
5. 代码说明
- 常量全部大写,单词用下划线分隔;
- 建造者使用链式调用,写法简洁直观;
- 所有语句块、运算符、标点符号严格遵守缩进与空格规范。
五、原型模式
1. 核心思想
以已有对象作为原型,通过克隆 / 复制的方式创建新对象,而非通过 new 重新执行完整构造逻辑。重点解决「对象创建成本高、结构高度相似」的问题。
2. 适用场景
- 对象初始化逻辑复杂、创建耗时较长(如加载资源、计算数据);
- 系统中存在大量结构相同、仅少量属性不同的对象;
- 需要动态创建对象,且不关心对象具体类型。
3. 优缺点
- 优点:大幅降低对象创建开销、简化创建代码;
- 缺点:需要处理深拷贝 / 浅拷贝问题,复杂嵌套对象克隆逻辑较麻烦。
4. 代码实现
// 定义克隆接口
interface Prototype_Interface {
Clone(): Prototype_Interface;
}
const MAX_SKILL_NUM = 3;
// 游戏角色类:实现克隆接口
class Game_Role implements Prototype_Interface {
public role_name: string;
public role_level: number;
public role_skill: string[];
constructor(name: string, level: number, skill: string[]) {
this.role_name = name;
this.role_level = level;
this.role_skill = skill;
}
// 克隆方法:生成新对象
public Clone(): Prototype_Interface {
// 简单浅拷贝
let new_skill = [...this.role_skill];
return new Game_Role(this.role_name, this.role_level, new_skill);
}
public Show_Role_Detail(): void {
console.log(`角色名:${this.role_name},等级:${this.role_level},技能:${this.role_skill.join("、")}`);
}
}
// 测试调用
// 创建原型对象
let origin_warrior = new Game_Role("战士", 60, ["猛击", "格挡", "冲锋"]);
origin_warrior.Show_Role_Detail();
// 基于原型克隆出新对象
let clone_warrior = origin_warrior.Clone() as Game_Role;
// 修改克隆对象属性,不影响原对象
clone_warrior.role_name = "狂战士";
clone_warrior.role_level = 65;
clone_warrior.Show_Role_Detail();
// 判断引用地址
if (origin_warrior != clone_warrior) {
console.log("克隆得到全新对象,与原对象不是同一实例");
}
5. 代码说明
- 抽取
Clone接口统一克隆规范,符合面向接口编程思想; - 常量命名、缩进、括号、空格全部遵循格式要求;
- 示例中做了数组浅拷贝,保证基础类型数据互不干扰。
六、创建型模式整体总结
- 单例模式:全局唯一实例,用于全局资源、配置、工具类;
- 工厂方法模式:一个工厂对应一个产品,产品扩展友好;
- 抽象工厂模式:一个工厂对应一整套产品族,保证组件配套使用;
- 建造者模式:针对属性繁多、参数可选的复杂对象,分步构建;
- 原型模式:以克隆方式创建对象,降低高成本对象的创建开销。
在 TypeScript 前端 / Node.js 项目中,可根据对象复杂度、扩展需求、创建成本灵活选择对应模式,让对象创建逻辑更规范、项目架构更健壮。
更多推荐


所有评论(0)