提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
——DP
UML类图
模式说明
抽象工厂与工厂方法在定义上最明显的区别是“创建一系列相关或相互依赖对象的接口”,由此可以看出抽象工厂强调的是要能创建多个对象,而且这些对象间有某种联系。例如我们系统提供了对SQL和Oracle两种数据库的支持,因此对于产品类和订单类,就有两种不同的实现。
产品类的实现:
/// <summary> /// 抽象业务模型(产品) /// </summary> abstract class Product { public string Name { get; set; } public abstract void Save(); } /// <summary> /// 产品模型(针对Oracle实现) /// </summary> class ProductWithOracle:Product { public override void Save() { Console.WriteLine("保存产品信息到Oracle"); } } /// <summary> /// 产品模型(针对SQL实现) /// </summary> class ProductWithSql : Product { public override void Save() { Console.WriteLine("保存产品信息到SQL"); } }
订单类的实现:
/// <summary> /// 抽象业务模型(订单) /// </summary> abstract class Order { public int Id { get; set; } public abstract void Save(); } /// <summary> /// 订单模型(针对Oracle实现) /// </summary> class OrderWithOracle:Order { public override void Save() { Console.WriteLine("保存订单信息到Oracle"); } } /// <summary> /// 订单模型(针对SQL实现) /// </summary> class OrderWithSql:Order { public override void Save() { Console.WriteLine("保存订单信息到SQL"); } }
下面定义一个用于创建产品和订单的工厂接口:
/// <summary> /// 抽象工厂接口 /// </summary> interface IFactory { Product CreateProduct(); Order CreateOrder(); }
提供SQL工厂的实现:
/// <summary> /// SQL工厂 /// </summary> class SqlFactory:IFactory { public Product CreateProduct() { return new ProductWithSql(); } public Order CreateOrder() { return new OrderWithSql(); } }
提供Oracle工厂的实现:
/// <summary> /// Oracle工厂 /// </summary> class OracleFactory : IFactory { public Product CreateProduct() { return new ProductWithOracle(); } public Order CreateOrder() { return new OrderWithOracle(); } }
客户端在决定使用何种数据库后,就可以用抽象工厂来创建针对这一数据库版本的具体业务对象了:
IFactory factory = new OracleFactory(); factory.CreateOrder().Save(); factory.CreateProduct().Save();
总结
抽象工厂主要是为了创建一系列相关(或相互依赖)的对象,如上文中的产品类和订单类,要么都是针对SQL数据库的,要么都是针对Oracle数据库的。如果此处用工厂方法模式,就有可能存在这种情况:用户用产品工厂创建了针对SQL的产品类,但却用订单工厂创建了针对Oracle的订单类,假如我们的系统在运行时只支持一种库,那么就留下严重的BUG,而此处用抽象工厂模式,就不会存在创建出的一系列对象间不协调的问题。
参考
- 程杰老师 《大话设计模式》