工厂模式属于创建型设计模式,核心思想是将对象的创建逻辑封装到独立的工厂类中,调用方不需要直接通过new关键字实例化对象,只需要向工厂传递对应的参数就能获取需要的实例,这样可以让代码更符合开闭原则,后续新增产品类型时不需要修改调用方的代码。

简单工厂模式实现
简单工厂模式是最基础的工厂模式实现,通过一个工厂类根据传入的参数判断需要创建的产品类型,适合产品类型较少且不会频繁变动的场景。
定义产品抽象类
首先定义一个产品的抽象基类,所有具体产品都继承这个基类,实现统一的抽象方法。
// 产品抽象基类
public abstract class Product
{
// 产品的通用方法
public abstract void Use();
}
定义具体产品类
接下来定义两个具体的产品类,分别继承Product基类,实现Use方法的具体逻辑。
// 具体产品A
public class ProductA : Product
{
public override void Use()
{
Console.WriteLine("使用产品A的功能");
}
}
// 具体产品B
public class ProductB : Product
{
public override void Use()
{
Console.WriteLine("使用产品B的功能");
}
}
实现简单工厂类
工厂类包含一个静态的创建方法,根据传入的产品类型参数返回对应的产品实例。
public class SimpleFactory
{
// 根据类型创建产品
public static Product CreateProduct(string productType)
{
switch (productType)
{
case "A":
return new ProductA();
case "B":
return new ProductB();
default:
throw new ArgumentException("不支持的产品类型");
}
}
}
调用示例
调用方只需要传入对应的类型参数,就能获取产品实例,不需要关心产品的创建细节。
class Program
{
static void Main(string[] args)
{
// 创建产品A
Product productA = SimpleFactory.CreateProduct("A");
productA.Use();
// 创建产品B
Product productB = SimpleFactory.CreateProduct("B");
productB.Use();
}
}
工厂方法模式实现
简单工厂模式的问题是如果新增产品类型,需要修改工厂类的switch逻辑,不符合开闭原则。工厂方法模式将工厂类抽象化,每个产品对应一个独立的工厂类,新增产品时只需要新增对应的工厂类即可。
定义抽象工厂接口
首先定义抽象工厂接口,声明创建产品的方法。
// 抽象工厂接口
public interface IFactory
{
Product CreateProduct();
}
定义具体工厂类
每个具体产品对应一个具体工厂类,实现抽象工厂接口,返回对应的产品实例。
// 产品A的工厂类
public class ProductAFactory : IFactory
{
public Product CreateProduct()
{
return new ProductA();
}
}
// 产品B的工厂类
public class ProductBFactory : IFactory
{
public Product CreateProduct()
{
return new ProductB();
}
}
调用示例
调用方根据需要使用的产品,选择对应的工厂类来创建实例。
class Program
{
static void Main(string[] args)
{
// 使用产品A的工厂创建产品A
IFactory factoryA = new ProductAFactory();
Product productA = factoryA.CreateProduct();
productA.Use();
// 使用产品B的工厂创建产品B
IFactory factoryB = new ProductBFactory();
Product productB = factoryB.CreateProduct();
productB.Use();
}
}
抽象工厂模式实现
抽象工厂模式适合需要创建一组相关或者相互依赖的产品的场景,比如不同品牌的电子产品包含手机、平板等多个产品,每个品牌的产品族对应一个抽象工厂的实现。
扩展产品体系
假设我们有两类产品,Product和Accessory,每个品牌都生产这两类产品,首先定义两个产品的抽象类。
// 主产品抽象类
public abstract class MainProduct
{
public abstract void ShowMainFunc();
}
// 配件产品抽象类
public abstract class AccessoryProduct
{
public abstract void ShowAccessoryFunc();
}
定义具体产品类
以品牌X和品牌Y为例,分别实现两个品牌的主产品和配件产品。
// 品牌X的主产品
public class BrandXMain : MainProduct
{
public override void ShowMainFunc()
{
Console.WriteLine("品牌X主产品功能");
}
}
// 品牌X的配件
public class BrandXAccessory : AccessoryProduct
{
public override void ShowAccessoryFunc()
{
Console.WriteLine("品牌X配件功能");
}
}
// 品牌Y的主产品
public class BrandYMain : MainProduct
{
public override void ShowMainFunc()
{
Console.WriteLine("品牌Y主产品功能");
}
}
// 品牌Y的配件
public class BrandYAccessory : AccessoryProduct
{
public override void ShowAccessoryFunc()
{
Console.WriteLine("品牌Y配件功能");
}
}
定义抽象工厂接口
抽象工厂接口声明创建主产品和配件产品的方法。
public interface IAbstractFactory
{
MainProduct CreateMainProduct();
AccessoryProduct CreateAccessoryProduct();
}
定义具体工厂类
每个品牌对应一个具体工厂类,实现抽象工厂接口,返回该品牌的全系列产品。
// 品牌X的工厂
public class BrandXFactory : IAbstractFactory
{
public MainProduct CreateMainProduct()
{
return new BrandXMain();
}
public AccessoryProduct CreateAccessoryProduct()
{
return new BrandXAccessory();
}
}
// 品牌Y的工厂
public class BrandYFactory : IAbstractFactory
{
public MainProduct CreateMainProduct()
{
return new BrandYMain();
}
public AccessoryProduct CreateAccessoryProduct()
{
return new BrandYAccessory();
}
}
调用示例
调用方只需要选择对应的品牌工厂,就能获取该品牌的所有产品,不需要关心具体产品的创建细节。
class Program
{
static void Main(string[] args)
{
// 使用品牌X的工厂
IAbstractFactory factoryX = new BrandXFactory();
MainProduct mainX = factoryX.CreateMainProduct();
AccessoryProduct accessoryX = factoryX.CreateAccessoryProduct();
mainX.ShowMainFunc();
accessoryX.ShowAccessoryFunc();
// 使用品牌Y的工厂
IAbstractFactory factoryY = new BrandYFactory();
MainProduct mainY = factoryY.CreateMainProduct();
AccessoryProduct accessoryY = factoryY.CreateAccessoryProduct();
mainY.ShowMainFunc();
accessoryY.ShowAccessoryFunc();
}
}
三种工厂模式的适用场景
不同工厂模式的适用场景有所区别,开发者可以根据实际需求选择合适的实现方式:
- 简单工厂模式:产品类型少且不会频繁新增,适合小型项目或者临时使用场景
- 工厂方法模式:产品类型可能会频繁扩展,需要符合开闭原则,适合中大型项目的单个产品维度扩展
- 抽象工厂模式:需要创建一组相关的产品族,产品有多个维度,适合需要批量创建关联产品的场景
注意事项
在使用工厂模式时需要注意以下几点:
- 不要为了用设计模式而用设计模式,如果对象创建逻辑非常简单,直接使用new实例化反而更清晰
- 工厂类的职责要单一,不要在一个工厂类里添加和产品创建无关的逻辑
- 如果使用依赖注入框架,可以结合框架的注册机制简化工厂模式的实现,不需要手动编写工厂类