一、简单工厂模式介绍
定义:简单工厂模式(Simple Factory Pattern),又称为静态工厂模式(Static Factory Pattern),是一种创建型设计模式。它专门定义一个类来负责创建其他类的实例,这些被创建的实例通常具有共同的父类,并且可以根据参数的不同返回不同类的实例。
结构:简单工厂模式包含三个角色:
- 工厂角色:负责实现创建所有实例的内部逻辑。
- 抽象产品角色:是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
- 具体产品角色:是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
用途:
- 封装对象的创建:将对象的创建过程封装在工厂类中,客户端不需要知道对象是如何被创建的。
- 解耦:降低了客户端与具体产品类之间的耦合度,使得系统更加灵活和可扩展。
- 便于维护:当需要修改对象的创建过程时,只需修改工厂类,而不需要修改客户端代码。
二、简单工厂模式代码实现
假设我们有一个接口Product
,以及两个实现了该接口的具体产品类ConcreteProductA
和ConcreteProductB
。
// 产品接口
public interface Product
{
string Barcode { get; } // 假设条码是只读的
void Use();
}
// 具体产品A
public class ConcreteProductA : Product
{
public string Barcode { get; private set; } = "A12345"; // 为产品A分配一个条码
public void Use()
{
Console.WriteLine("Using ConcreteProductA with Barcode: " + Barcode);
}
}
// 具体产品B
public class ConcreteProductB : Product
{
public string Barcode { get; private set; } = "B67890"; // 为产品B分配一个条码
public void Use()
{
Console.WriteLine("Using ConcreteProductB with Barcode: " + Barcode);
}
}
// 工厂类(无需修改,因为接口的变化没有影响到工厂类的创建逻辑)
public class SimpleFactory
{
public static Product CreateProduct(string type)
{
Product product = null;
switch (type)
{
case "A":
product = new ConcreteProductA();
break;
case "B":
product = new ConcreteProductB();
break;
default:
throw new ArgumentException("Unknown product type");
}
return product;
}
}
// 客户端代码(无需修改,因为接口的变化没有影响到客户端的使用方式)
public class Client
{
public static void Main()
{
Product productA = SimpleFactory.CreateProduct("A");
productA.Use(); // 输出: Using ConcreteProductA with Barcode: A12345
Product productB = SimpleFactory.CreateProduct("B");
productB.Use(); // 输出: Using ConcreteProductB with Barcode: B67890
}
}
SimpleFactory
类根据传入的字符串参数type
来创建并返回相应的Product
对象。客户端代码通过调用SimpleFactory.CreateProduct
方法来获取所需的产品对象,而无需知道具体的产品实现类。这样就实现了对象的创建与使用之间的解耦。
三、简单工厂代码在C#中的升级
SimpleFactory类
的枚举在每次增加新的产品类时,都要需要修改一下枚举,非常的麻烦。但是C#本身提供了泛型<T>,完全可以将产品类作为泛型对象传入,然后直接创建这个产品类对象,再以父类形式返回。
代码实现如下(在原来SimpleFactory类
代码上增加了一个重载函数,和调用代码):
// 产品接口
public interface Product
{
string Barcode { get; } // 假设条码是只读的
void Use();
}
// 具体产品A
public class ConcreteProductA : Product
{
public string Barcode { get; private set; } = "A12345"; // 为产品A分配一个条码
public void Use()
{
Console.WriteLine("Using ConcreteProductA with Barcode: " + Barcode);
}
}
// 具体产品B
public class ConcreteProductB : Product
{
public string Barcode { get; private set; } = "B67890"; // 为产品B分配一个条码
public void Use()
{
Console.WriteLine("Using ConcreteProductB with Barcode: " + Barcode);
}
}
// 工厂类(无需修改,因为接口的变化没有影响到工厂类的创建逻辑)
public class SimpleFactory
{
public static Product CreateProduct(string type)
{
Product product = null;
switch (type)
{
case "A":
product = new ConcreteProductA();
break;
case "B":
product = new ConcreteProductB();
break;
default:
throw new ArgumentException("Unknown product type");
}
return product;
}
public static Product CreateProduct<T>()
{
return (Product)Activator.CreateInstance(typeof(T));
}
}
// 客户端代码(无需修改,因为接口的变化没有影响到客户端的使用方式)
public class Client1
{
public static void Main1()
{
var product_a=SimpleFactory.CreateProduct<ConcreteProductA>();
var product_b=SimpleFactory.CreateProduct<ConcreteProductB>();
product_a.Use();// 输出: Using ConcreteProductA with Barcode: A12345
product_b.Use();// 输出: Using ConcreteProductB with Barcode: B67890
Product productA = SimpleFactory.CreateProduct("A");
productA.Use(); // 输出: Using ConcreteProductA with Barcode: A12345
Product productB = SimpleFactory.CreateProduct("B");
productB.Use(); // 输出: Using ConcreteProductB with Barcode: B67890
}
}