2. 工厂方法模式(Factory Method)
2. 工厂方法模式(Factory Method)
问题:创建对象的逻辑分散在各处,想统一管理。
核心:把 new 的过程封装到工厂函数里,调用者不关心具体类。
interface Pet {
speak(): string;
}
class Dog implements Pet {
speak(): string { return '汪汪'; }
}
class Cat implements Pet {
speak(): string { return '喵喵'; }
}
type PetType = 'dog' | 'cat';
function createPet(type: PetType): Pet {
switch (type) {
case 'dog': return new Dog();
case 'cat': return new Cat();
default: throw new Error(`未知类型: ${type}`);
}
}
const pet = createPet('dog');
console.log(pet.speak()); // 汪汪package factory
import "fmt"
type Pet interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string { return "汪汪" }
type Cat struct{}
func (c Cat) Speak() string { return "喵喵" }
func CreatePet(kind string) (Pet, error) {
switch kind {
case "dog":
return Dog{}, nil
case "cat":
return Cat{}, nil
default:
return nil, fmt.Errorf("未知类型: %s", kind)
}
}实战场景
- 通知渠道创建:根据
email、sms、webhook、push创建不同发送器,业务代码只调用统一的send()。 - 支付方式接入:根据订单选择支付宝、微信、银行卡、Stripe 等支付客户端,把创建细节和鉴权参数封装起来。
- 文件解析器:上传
.csv、.json、.xlsx、.xml时,根据文件类型创建对应 parser,调用者只关心解析后的结构化数据。 - 导出器生成:后台报表按用户选择导出 PDF、Excel、CSV 或图片,工厂负责返回不同 exporter。
- UI 组件创建:低代码平台、表单引擎或配置化页面根据
type: 'input' | 'select' | 'date'创建不同控件。 - 数据库驱动选择:根据配置创建 MySQL、PostgreSQL、SQLite 或测试用内存数据库连接。
- 第三方 API 客户端:同一个业务能力可能有多个供应商,例如短信、地图、对象存储,工厂根据地区或租户返回对应客户端。
- 测试替身创建:测试环境返回 fake client 或 mock repository,生产环境返回真实实现,业务层不需要知道自己拿到的是哪一种。
- 领域对象恢复:从数据库记录或消息队列 payload 恢复不同类型的领域对象,例如普通订单、预售订单、退款单。
- 插件系统:根据插件 manifest 的类型加载不同插件实例,让新增插件时只扩展工厂映射,而不是改散落在各处的
new。