工厂模式是解决调用者与被调用者耦合度过高的问题。工厂模式是一步一步演化过来的,分为简单工厂模式和抽象工厂模式。这个章节介绍简单工厂模式。我们的情形很简单,我们需要产品A(ProductA)和产品B(ProductB).
Class ProductA:
namespace SimpleFactory
{
public class ProductA
{
public ProductA()
{
Console.WriteLine("ProductA created.");
}
}
}
Class ProductB
namespace SimpleFactory
{
public class ProductB
{
public ProductB()
{
Console.WriteLine("ProductB created.");
}
}
}
调用者:
namespace SimpleFactory
{
class Program
{
static void Main(string[] args)
{
ProductA pA = new ProductA();
ProductB pB = new ProductB();
Console.ReadKey();
}
}
}
结果:
进一步我们需要产品C,我们需要增加一个ProductC类,然后new ProductC的实例。这样我们就会出现很多类的实例。调用者持有很多类的引用,而同一时刻我们只需要一个引用就足够了。我们能否改进这种做法呢。我们抽象出一个Product类,让ProductA,ProductB去继承这两个类。
Product:
namespace SimpleFactory
{
public abstract class Product
{
}
}
调用者:
class Program
{
static void Main(string[] args)
{
Product p = null;
p = new ProductA();
p = new ProductB();
Console.ReadKey();
}
}
ProductA,ProductB不变。
我们可以看到,我们使用父类的引用指向子类的实例,这样同一时刻只有一个引用。输出结构不变。
进一步,我们目前还是调用则在构造对象,尽管解决了对个引用的问题,我们可否不让调用者自己构造对象呢,答案是可以的。
我们构造一个产品工厂(ProductFactory),然后让产品工厂根据产品类型(ProductType)构造产品,调用者只需要告诉工厂,我需要什么类型的产品就可以了。
ProductType:
namespace SimpleFactory
{
public enum ProductType
{
ProductA,
ProductB
}
}
ProductFactory
namespace SimpleFactory
{
public class ProductFactory
{
public Product CreateProduct(ProductType type)
{
Product p = null;
switch (type)
{
case ProductType.ProductA:
p = new ProductA();
break;
case ProductType.ProductB:
p = new ProductB();
break;
}
return p;
}
}
}
调用者就很很简单了:
class Program
{
static void Main(string[] args)
{
ProductFactory pf = new ProductFactory();
Product p = null;
p = pf.CreateProduct(ProductType.ProductA);
p = pf.CreateProduct(ProductType.ProductB);
Console.ReadKey();
}
}
简单工程分离了调用者和服务者的职责,更加符合SOLID原则之一的单一职责原则。简单工厂目前还不符合"对扩展开放,对修改封闭"的原则,因为要增加产品还需要修改工厂逻辑,抽象工厂模式会解决这个问题。
工厂模式通常应用于应用程序对于多数据库支持的数据库访问模块。