在面向对象编程(OOP)的世界中,简单工厂模式(Simple Factory Pattern) 是一种非常常见且实用的设计模式。虽然它并不属于GoF(Gang of Four)定义的23种经典设计模式之一,但它是理解更复杂模式(如工厂方法模式)的重要铺垫。本文将深入解析简单工厂模式的工作原理、实现方式及其在实际项目中的作用。
一、什么是简单工厂模式?
简单工厂模式是一种创建型设计模式,它的核心思想是:根据输入的参数或条件,返回一个特定类的实例。这些类通常继承自同一个基类或接口,具有相同的方法签名,但方法的具体实现可能不同。
简单工厂模式通过一个“工厂”类来封装对象的创建逻辑,使得客户端无需关心具体的对象创建过程,只需要调用工厂提供的接口即可获取所需对象。
二、简单工厂模式的结构解析
我们通过一个类图来理解简单工厂模式的核心组成部分:
- 基类(Base Class):定义了所有子类共有的接口。
- 具体类(Concrete Classes):继承自基类,实现具体的业务逻辑。
- 工厂类(Factory Class):根据传入的参数决定返回哪一个具体类的实例。
以一个名字解析器为例,假设我们有如下类结构:
Namer
:基类,提供基础属性和方法。FirstFirst
:表示“firstname lastname”格式。LastFirst
:表示“lastname, firstname”格式。NamerFactory
:简单工厂类,根据输入判断使用哪个具体类解析名字。
三、一个C#示例:名字解析器
1. 定义基类 Namer
public class Namer
{
protected string frName, lName;
public string GetFrname()
{
return frName;
}
public string GetLname()
{
return lName;
}
}
该类定义了两个受保护的字段 frName
和 lName
,并提供公共方法来获取它们。
2. 实现具体类 FirstFirst
和 LastFirst
FirstFirst
类处理“firstname lastname”格式:
public class FirstFirst : Namer
{
public FirstFirst(string name)
{
int i = name.Trim().IndexOf(" ");
if (i > 0)
{
frName = name.Substring(0, i).Trim();
lName = name.Substring(i + 1).Trim();
}
else
{
lName = name;
frName = "";
}
}
}
LastFirst
类处理“lastname, firstname”格式:
public class LastFirst : Namer
{
public LastFirst(string name)
{
int i = name.IndexOf(",");
if (i > 0)
{
lName = name.Substring(0, i);
frName = name.Substring(i + 1).Trim();
}
else
{
lName = name;
frName = "";
}
}
}
这两个派生类都通过构造函数对传入的字符串进行解析,并将结果保存在基类字段中。
3. 构建简单工厂类 NamerFactory
public class NamerFactory
{
public Namer CreateNamer(string name)
{
if (name.Contains(","))
return new LastFirst(name);
else
return new FirstFirst(name);
}
}
工厂类根据输入是否包含逗号来决定返回哪一个具体类的实例。
4. 客户端调用示例
class Program
{
static void Main(string[] args)
{
NamerFactory factory = new NamerFactory();
Namer namer1 = factory.CreateNamer("John Doe");
Console.WriteLine($"First Name: {namer1.GetFrname()}, Last Name: {namer1.GetLname()}");
Namer namer2 = factory.CreateNamer("Doe, John");
Console.WriteLine($"First Name: {namer2.GetFrname()}, Last Name: {namer2.GetLname()}");
}
}
输出结果:
First Name: John, Last Name: Doe
First Name: John, Last Name: Doe
四、简单工厂模式的优点与局限
✅ 优点:
- 封装对象创建逻辑:客户端不需要关心具体类的创建过程,只需调用工厂接口。
- 提高可扩展性:新增一个具体类只需修改工厂逻辑,而不影响已有代码。
- 统一接口:所有返回对象都继承自同一个基类或接口,便于统一调用。
⚠️ 局限:
- 违反开放封闭原则:每次新增一个具体类,都需要修改工厂类的判断逻辑。
- 不适合大规模扩展:当具体类数量激增时,判断逻辑会变得复杂且难以维护。
- 不属于GoF模式:不被广泛认为是“标准”的设计模式,需谨慎使用。
五、简单工厂模式的适用场景
- 产品种类有限:适用于需要创建的对象类型不多的场景。
- 简化客户端调用:当客户端不希望处理复杂的对象创建逻辑时。
- 作为工厂方法模式的前奏:为后续引入更高级的工厂方法模式打下基础。
六、从简单工厂到工厂方法模式的演进
简单工厂模式虽然实用,但其“集中决策”的特性限制了它的扩展性。在工厂方法模式中,每个具体类都有自己的工厂类,客户端通过调用不同的工厂来获取实例,从而实现对扩展开放、对修改关闭的设计原则。
例如:
public interface INamerFactory
{
Namer CreateNamer(string name);
}
public class FirstFirstFactory : INamerFactory
{
public Namer CreateNamer(string name)
{
return new FirstFirst(name);
}
}
这种结构允许系统在不修改现有代码的情况下灵活扩展新的产品类型。
结语:选择合适的模式,构建高质量系统
简单工厂模式作为一个轻量级的设计模式,非常适合在中小型项目或模块中使用。它可以帮助我们快速实现对象的创建逻辑封装,提高代码的可读性和可维护性。然而,随着业务逻辑的复杂化和对象种类的增加,我们应考虑向更高级的设计模式(如工厂方法模式、抽象工厂模式)进行演进。
设计模式的本质,不是为了炫技,而是为了更好地组织代码、提高系统的可维护性与可扩展性。