提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

——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,而此处用抽象工厂模式,就不会存在创建出的一系列对象间不协调的问题。

参考

  1. 程杰老师  《大话设计模式》

设计模式——抽象工厂(Abstract Factory)的更多相关文章

  1. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  2. 面向对象设计——抽象工厂(Abstract Factory)模式

    定义 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类.抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道或关心实际产出的具体产品是什么.这样一来,客户就能从具体的产 ...

  3. 设计模式四: 抽象工厂(Abstract Factory)

    简介 抽象工厂模式是创建型模式的一种, 与工厂方法不同的是抽象工厂针对的是生产一组相关的产品, 即一个产品族. 抽象工厂使用工厂方法模式来生产单一产品, 单一产品的具体实现分别属于不同的产品族. 抽象 ...

  4. 【设计模式】——抽象工厂Abstract Factory

    模式意图 提供对象的使用接口,隐藏对象的创建过程. 模式结构 AbstractFactory 提供创建对象的接口. ConcreteFactory 提供真正创建对象的实现类,用于组合并创建不同的对象, ...

  5. 5、抽象工厂 abstract factory 将关联组件组成产品 创建型模式

    趁热打铁,紧跟着上一节的工厂方法模式.这一节介绍一下抽象工厂模式,以及分析俩个模式的不同 1.何为抽象模式? 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他 ...

  6. 工厂模式[3] 抽象工厂 Abstract Factory

    简介 1.简单工厂,或静态工厂,产品接口 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类或实现同一接口 优点:客户端可以直接消费产品,而不必关心具体产品的实现(不关心对象的 ...

  7. C2:抽象工厂 Abstract Factory

    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 应用场景: 一系列相互依赖的对象有不同的具体实现.提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合 UM ...

  8. Java 工厂模式(一)— 抽象工厂(Abstract Factory)模式

    一.抽象工厂模式介绍: 1.什么是抽象工厂模式: 抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态,抽象工厂模式向客户端提供一个接口,使得客户端在不知道具体产品的情类型的情况下,创建 ...

  9. Headfirst设计模式的C++实现——抽象工厂(Abstract Factory)

    Dough.h #ifndef _DOUGH_H #define _DOUGH_H class Dough { }; #endif ThinCrustDough.h #ifndef _THIN_CRU ...

随机推荐

  1. Cloudera安装要点

    C方式是完全离线方式 https://www.cloudera.com/documentation/enterprise/5-10-x/topics/cm_ig_installing_configur ...

  2. VS2008中_T的作用

    引用: VC++里面定义字符串的时候,用_T来保证兼容性.VC++支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改. 如 ...

  3. [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出

    前几天,将Visual studio 2013 update 3 升级到了update 5.打开原来的解决方案,出现了 未找到与约束 contractname Microsoft.VisualStud ...

  4. shell分库备份

    分库备份企业实战题7:如何实现对MySQL数据库进行分库备份,请用脚本实现 #!/bin/bash MysqlUser=root PassWord=root Port= Socket="/u ...

  5. (补)Java解析XML之dom4j

    上次记得忘了记最流行的dom4j方法了,用的还是上次的那个XML文件 注:需要添加dom4j.jar文件 package com.xujingyang.dom4j; import org.dom4j. ...

  6. Unity实现支持泛型的事件管理以减少使用object作为参数带来的频繁装拆箱

    如果不用C#自身的event关键字而是要自己实现一个可统一管理游戏中各种消息事件通知管理的系统模块EventManger时,通常都是把事件delegate的参数定义为object类型以适应所有的数据类 ...

  7. SpringBoot02 Controller的使用、数据库操作、事物管理、修改banner

    1 Controller的使用 特点:编程技巧和SpringMVC几乎完全一样 注意:@RestController = @Controller + @ResponseBody 注意:读取路径参数和请 ...

  8. JavaScript学习系列4 ----- JavaScript中的扩展运算符 三个点(...)

    在JavaScript中, ES6开始有rest参数 和 三个点扩展运算符 (spread运算符) 我们来看看他们各自的用处 1. rest参数 rest参数的形式为 ...变量名          ...

  9. CCS中如何新建Platform以及调用

    新建Platform: Debug模式下,选择tools -> RTSC Tools -> Platform -> New,根据自己的需要选择Platform保存的路径以及对应的芯片 ...

  10. 20169201 2016-2017-2 实验二《Java面向对象程序设计》

    实验一:程序设计中临时变量的使用 代码托管 1.删除数组中的元素5 for(int i = 4; i < arr.length - 1; i ++){ arr[i] = arr[i + 1]; ...