一、 抽象工厂(Abstract Factory)模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family)。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。如图:

图中一共有四个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。

引进抽象工厂模式

所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。如果用图来描述的话,如下图:

二、 Abstract Factory模式的结构


抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。

具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。

抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。

具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

三、 程序举例
该程序演示了抽象工厂的结构,本身不具有任何实际价值。

// "AbstractProductA"
abstract class AbstractProductA
{
}// "AbstractProductB"
abstract class AbstractProductB
{// Methodsabstract public void Interact( AbstractProductA a );
}// "ProductA1"
class ProductA1 : AbstractProductA
{
}// "ProductB1"
class ProductB1 : AbstractProductB
{// Methodsoverride public void Interact( AbstractProductA a ){Console.WriteLine( this + " interacts with " + a );}
}// "ProductA2"
class ProductA2 : AbstractProductA
{
}// "ProductB2"
class ProductB2 : AbstractProductB
{// Methodsoverride public void Interact( AbstractProductA a ){Console.WriteLine( this + " interacts with " + a );}
}// "Client" - the interaction environment of the products
class Environment
{// Fieldsprivate AbstractProductA AbstractProductA;private AbstractProductB AbstractProductB;// Constructorspublic Environment( AbstractFactory factory ){AbstractProductB = factory.CreateProductB();AbstractProductA = factory.CreateProductA();}// Methodspublic void Run(){AbstractProductB.Interact( AbstractProductA );}
}/// <summary>
/// ClientApp test environment
/// </summary>
class ClientApp
{public static void Main(string[] args){AbstractFactory factory1 = new ConcreteFactory1();Environment e1 = new Environment( factory1 );e1.Run();AbstractFactory factory2 = new ConcreteFactory2();Environment e2 = new Environment( factory2 );e2.Run();}
}

四、 在什么情形下使用抽象工厂模式:

在以下情况下应当考虑使用抽象工厂模式:

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
这个系统有多于一个的产品族,而系统只消费其中某一产品族。
同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

五、 抽象工厂的起源
据说最早的应用是用来创建在不同操作系统的视窗环境下都能够运行的系统。比如在Windows与Unix系统下都有视窗环境的构件,在每一个操作系统中,都有一个视窗构件组成的构件家族。我们可以通过一个抽象角色给出功能描述,而由具体子类给出不同操作系统下的具体实现,如图:

六、 Abstract Factory模式在实际系统中的实现
Herbivore:草食动物
Carnivore:食肉动物
Bison:[‘baisn],美洲或欧洲的野牛

下面实际代码演示了一个电脑游戏中创建不同动物的抽象工厂。尽管在不同大陆下动物物种是不一样的,但动物间的关系仍然保留了下来。

using System;// "AbstractFactory"
abstract class ContinentFactory
{// Methodsabstract public Herbivore CreateHerbivore();abstract public Carnivore CreateCarnivore();
}// "ConcreteFactory1"
class AfricaFactory : ContinentFactory
{// Methodsoverride public Herbivore CreateHerbivore(){ return new Wildebeest(); }override public Carnivore CreateCarnivore(){ return new Lion(); }
}// "ConcreteFactory2"
class AmericaFactory : ContinentFactory
{// Methodsoverride public Herbivore CreateHerbivore(){ return new Bison(); }override public Carnivore CreateCarnivore(){ return new Wolf(); }
}// "AbstractProductA"
abstract class Herbivore
{
}// "AbstractProductB"
abstract class Carnivore
{// Methodsabstract public void Eat( Herbivore h );
}// "ProductA1"
class Wildebeest : Herbivore
{
}// "ProductB1"
class Lion : Carnivore
{// Methodsoverride public void Eat( Herbivore h ){// eat wildebeestConsole.WriteLine( this + " eats " + h );}
}// "ProductA2"
class Bison : Herbivore
{
}// "ProductB2"
class Wolf : Carnivore
{// Methodsoverride public void Eat( Herbivore h ){// Eat bisonConsole.WriteLine( this + " eats " + h );}
}// "Client"
class AnimalWorld
{// Fieldsprivate Herbivore herbivore;private Carnivore carnivore;// Constructorspublic AnimalWorld( ContinentFactory factory ){carnivore = factory.CreateCarnivore();herbivore = factory.CreateHerbivore();}// Methodspublic void RunFoodChain(){ carnivore.Eat(herbivore); }
}/// <summary>
///  GameApp test class
/// </summary>
class GameApp
{public static void Main( string[] args ){// Create and run the Africa animal worldContinentFactory africa = new AfricaFactory();AnimalWorld world = new AnimalWorld( africa );world.RunFoodChain();// Create and run the America animal worldContinentFactory america = new AmericaFactory();world = new AnimalWorld( america );world.RunFoodChain();}
}

七、 “开放-封闭”原则
“开放-封闭”原则要求系统对扩展开放,对修改封闭。通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:

增加产品族:Abstract Factory很好的支持了”开放-封闭”原则。

增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持”开放-封闭”原则。

综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。

8. 工厂设计模式(factory pattern)相关推荐

  1. 类对象工厂设计模式(Factory Pattern)

    本文朋友在深圳逛街的时候突然想到的...这段时间就有想写几篇关于类对象的笔记,所以回家到之后就奋笔疾书的写出来发布了 提供了比工厂模式更高一级的接口级,用于返回若个工厂之一.这个模式是属于创立模式之一 ...

  2. 工厂设计模式(Factory Pattern)

    提供了比工厂模式更高一级的接口级,用于返回若个工厂之一.这个模式是属于创建模式之一.有几点值得注意: 对象的创建充分重用重要的代码. 对象的创建需要访问某个信息或者资源时,这对象不应该包含在组合类中. ...

  3. 设计模式(四)——工厂模式(Factory Pattern)

    工厂模式(Factory Pattern) 意义 工厂模式 实现了创建者和调用者的分离.将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦.从而提高项目的扩展和维护性 ...

  4. 设计模式 - 学习笔记 - 工厂模式Factory Pattern

    设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...

  5. 设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern。

    设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern. 文章目录 设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern. eg. 简单工厂模式. 结构. 优 ...

  6. 设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)

    工厂模式 Factory Pattern(简单工厂.工厂方法.抽象工厂) 工厂模式-创建型模式-提供了创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过一个共同的接口来 ...

  7. Spring模式系列(二) 工厂模式(Factory Pattern) - 理解Spring的第一课

    factory pattern在spring的用法 Beanfactory spring框架最依赖的模式,没有之一 这也许是最多程序员使用过的模式之一,我也在我的项目中用过很多次.工厂模式贯穿于整个S ...

  8. 【设计模式】工厂模式 Factory Pattern

    1)简单工厂(不是模式) 简单工厂只是一种变成习惯,并非23种设计模式之一. 简单工厂提供将实例话那种类型留给运行时判断,而非编译时指定.简单工厂模式就是由一个工厂类根据传入的参数决定创建出哪一个类的 ...

  9. 设计模式 抽象工厂(Abstract Factory Pattern)

    抽象工厂模式,比工厂模式具有更高层次的抽象.当要返回一系列相关类中的某一个,而每个类都能根据需要返回不同的对象时,可以使用这种模式.换句话说,抽象工厂是一个工厂对象,他能返回一系列相关类中的一个类.可 ...

  10. JAVA设计模式Design Pattern→单例模式Singleton Pattern、工厂模式Factory Pattern、代理模式Proxy Pattern

    私有化构造函数的类可以提供相应的 "接口"(一般就是静态方法)来返回自己的唯一实例供外部调用,像这样的确保只生成一个实例的模式被称作单例模式. 工厂模式,一个模型,用来大规模的生产 ...

最新文章

  1. 计算机工程实践,【计算机工程论文】计算机工程实践能力培养(共3056字)
  2. R语言使用ggExtra包的ggMarginal函数在散点图的顶部和右侧添加边缘直方图、自定义边缘直方图不同分组的填充色(Coloring Marginal Histograms)
  3. 快速排序 python菜鸟教程-Python菜鸟文本处理4种方法
  4. 在winform中使用三层架构学习总结
  5. Linux参数顺序,【每日一linux命令3】参数(或称选项)顺序
  6. redhat enterprise linux 5 上安装openoffice3.0 1
  7. mysql数据库搜索引擎要先进入_Mysql搜索引擎都有哪些区别
  8. ajax 购物车 c#,C#AJAX实例
  9. 光刻机的“崛起秘密”,第一本ASML的企业成长传记来了!
  10. 【CC3200AI 实验教程11】疯壳·AI语音人脸识别(会议记录仪/人脸打卡机)-AI语音系统架构
  11. 复变函数:复数基本知识、欧拉公式、复变函数的导数、解析函数
  12. animation之二,使用xml控制animat…
  13. 华为认证大数据工程师 HCIA-Big Data V3.5(中文版) 发布通知
  14. 如何用计算机巧记英语词汇,小学英语单词巧记法
  15. 程序员520❤七夕情人节表白代码Html+Js+Css花瓣相册网页模板❤程序员表白必备
  16. SpringBoot RabbitMQ 整合使用
  17. CSS 样式,如何计算临近颜色值?
  18. 使用Excel宏功能将考勤记录生成上班工时表
  19. 什么是软件开发领域的 obsolete 或者 deprecated 含义
  20. i.MX6ULL驱动开发 | 12 - 基于 Linux I2C 驱动读取AP3216C传感器

热门文章

  1. Java 线程池学习
  2. 基于Tight VNC的远程协助功能的实现
  3. Dojo1.6新特性概览
  4. 互联网公司是如何腐败的?
  5. R语言ETL工程:插入与合并(add/bind)
  6. R语言实战:个人贷款违约预测模型
  7. 天气太热业绩差,除了设坛求雨外,数据分析师还能干啥?
  8. 【R图秀-2】社交网络数据可视化(一)
  9. VB.NET自动操作其他程序(4)--读取、设置其他软件listview控件的内容
  10. 美图拟收购乐游科技附属公司约30%股份 后者为Warframe开发商