创建型模式之抽象工厂(Abstract Factory)
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
适用情况:
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当你提供一个产品类库,而只想显示它们的接口而不是实现时。
此模式的UML图如下:
我举一个例子来说明使用抽象工厂模式的优势:
我们开发系统经常需要与数据库连接,但是数据库的种类有很多,与数据库连接所依赖的对象也不同,如果使用抽象工厂模式,只需要用户根据不同的数据库实例化不同的工厂对象,由于这些工厂对象都是由同一个接口实现的,所以用户就不必对每种数据库的连接方式都了解,只需要调用接口的抽象方法即可。
使用抽象工厂模式的一般思路:
先为我们需要的某一类产品都申明一个接口,这里是动物和人:
public interface Animal
{
void Introduce();
}
public interface Human
{
void Introduce();
}
接着为产品的接口提供具体的实现:
public class Cat : Animal
{
public Cat()
{
Console.WriteLine("I'm cat.");
}
public void Introduce()
{
Console.WriteLine("喵喵喵!");
}
}
public class Dog : Animal
{
public Dog()
{
Console.WriteLine("I'm dog.");
}
public void Introduce()
{
Console.WriteLine("汪汪汪!");
}
}
public class Chinese : Human
{
public Chinese()
{
Console.WriteLine("I'm Chinese.");
}
public void Introduce()
{
Console.WriteLine("初次见面,请多多指教!");
}
}
public class Japaniese : Human
{
public Japaniese()
{
Console.WriteLine("I'm Japaniese.");
}
public void Introduce()
{
Console.WriteLine("始めました、よとしくお願いします!");
}
}
然后构建抽象工厂:
public interface AbstractFactory
{
Human m_Human();
Animal m_Animal();
}
实现不同的工厂:
public class ConcreteFactory1 : AbstractFactory
{
public Human m_Human()
{
return new Chinese();
}
public Animal m_Animal()
{
return new Cat();
}
}
public class ConcreteFactory2 : AbstractFactory
{
public Human m_Human()
{
return new Japaniese();
}
public Animal m_Animal()
{
return new Dog();
}
}
写一个测试的Main方法:
class Program
{
static void Main(string[] args)
{
AbstractFactory product1 = new ConcreteFactory1();
AbstractFactory product2 = new ConcreteFactory2();
product1.m_Human().Introduce();
product1.m_Animal().Introduce();
product2.m_Human().Introduce();
product2.m_Animal().Introduce();
}
}
运行结果:
我们不难发现:抽象工厂模式,难以支持新种类的产品,难以扩展抽象工厂以生产新种类的产品。因为AbstractFactory接口确定了可以被创建的产品集合。支持新种类的产品就需要扩展该工厂接口,这又将涉及AbstractFactory类及所有子类的改变。
这个问题我思考了很久,一种可行的方式是利用C#的反射机制,产品类的创建时使用泛型传递参数,这种实现方法今后有时间可以尝试去写。