该用new时适用于对象创建逻辑简单、无动态选择或生命周期管理需求的场景;当需根据配置选实现、复用单例、延迟初始化或统一管理生命周期时,应使用工厂模式。

什么时候该用 new,什么时候该用工厂?
直接 new 一个类,简单粗暴;但一旦对象创建逻辑变复杂(比如要根据配置选实现、要复用单例、要延迟初始化、要统一管理生命周期),new 就成了散落各处的硬编码点。工厂模式本质是把“怎么造对象”这个决策集中起来——不是为了炫技,而是为了后续改起来不翻车。
常见触发信号包括:if-else 或 switch 块里反复判断类型再 new;多个地方重复写相同的构造参数;单元测试时无法替换依赖;DI 容器还没引入但已有解耦需求。
SimpleFactory:适合小项目快速隔离创建逻辑
它不是 GoF 23 种之一,但最轻量、最常用。就是一个静态方法,输入条件,返回具体实例。
示例:
public static class PaymentFactory
{
public static IPayment Create(string type)
{
return type.ToLower() switch
{
"alipay" => new AlipayPayment(),
"wechat" => new WechatPayment(),
"paypal" => new PaypalPayment(),
_ => throw new ArgumentException($"Unknown payment type: {type}")
};
}
}注意点:
- 别让它承担太多职责——不负责对象生命周期(比如不释放资源),也不做复杂策略组合
- 如果
type来自用户输入或配置文件,务必校验并预热缓存,避免每次调用都走反射或字符串匹配 - 它和调用方仍存在编译期依赖,不适合需要彻底解耦的场景
Factory Method:当子类需要控制对象创建时
父类定义抽象工厂方法,子类决定实例化哪个类。适用于有明确继承体系、且创建逻辑随子类变化的场景,比如不同平台导出器(WindowsExporter / LinuxExporter)。
关键结构:
- 基类声明
protected abstract IExporter CreateExporter(); - 子类重写该方法,返回各自平台的具体实现
- 基类中其他方法(如
Export())只调用CreateExporter(),不关心具体类型
好处是开闭原则体现明显:加新平台只需新增子类,不用动原有工厂逻辑。但要注意——如果子类数量多、差异小,容易导致类爆炸,这时不如用参数化工厂 + 策略模式。
Abstract Factory:创建「一族」相关对象,而非单个
当你需要保证一组对象(比如 UI 控件:按钮、文本框、下拉框)风格统一(WinUIFactory vs MacUIFactory),且它们之间有协作关系时,才用它。C# 中典型表现是一组接口 + 多个配套实现 + 一个返回这些接口的工厂接口。
示例接口定义:
public interface IGUIFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
<p>public interface IButton { void Render(); }
public interface ITextBox { void Render(); }陷阱提醒:
- 别为了用而用——90% 的业务代码根本不需要跨“族”切换,硬套
Abstract Factory只会让代码更难读 - C# 里常被
IServiceProvider或第三方 DI 容器替代,尤其在 ASP.NET Core 中,services.AddSingleton<iguifactory winuifactory>()</iguifactory>更自然 - 如果某族里某个组件暂时没实现,工厂方法返回
null或抛异常都得明确约定,否则调用方容易 NRE
真正难的不是写出三种工厂结构,而是判断当前需求到底卡在哪一层抽象上——多数时候,一个带缓存的 SimpleFactory 加上配置驱动,已经覆盖了 80% 的实际场景。


















