首先啰嗦下创建迷宫所用的Room类。这个类并不直接保存Room四周的构造,而是通过MapSite* _sides[4]这个私有数组成员指向Room四周的构造。那么什么时候将四周构造直接放在Room中,什么时候通过指针访问,这两种方式各有神马优缺点?这是个问题[2015.10.07:你无法预先确定四周构造的具体类型,所以没办法将其直接放在Room中,只能使用基类指针]……不过这不是Abstract Fractory的重点,先放一边吧。

就“Factory”这个词的本义来说,上面这张图本身就够抽象的。让我们用更贴近“Factory”一词的汽车厂来作例子。

在遥远的北方大陆上有两家汽车厂,一家是BMW,一家是Benz。他们生产的汽车只有两个部件:方向盘和轮子(别问我这样的汽车怎么开)。于是我们的Abstract Factory有两个Virtual方法:CreateSteering,CreateWheel。自然,BMWFactory和BenzFactory各自造出的轮子和方向盘是有区别的。

另一方面,不管BMW的轮子还是Benz的轮子,都是圆的,能在地上滚动的;方向盘同样有其共同点。所以我们有AbstractSteering和AbstractWheel以及它们的派生类。

综上,“工厂”有“抽象工厂”和具体的“实际工厂”;

“工厂产品”有“抽象产品”和具体的“实际产品”。

“工厂类”和其生产产品的“产品类”是分开的,但各个工厂生产的产品种类是一样的,这样才能在Factory Class和Product Class之间建立对应关系。

下面是代码:

 // 编译环境:VS2008
// AbstractFactory.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream> using namespace std; class AbstractWheel
{
public: }; class BenzWheel : public AbstractWheel
{
public:
BenzWheel()
{
cout << "I am BenzWheel" << endl;
}
}; class BMWWheel : public AbstractWheel
{
public:
BMWWheel()
{
cout << "I am BMWWheel" << endl;
}
}; class AbstractSteering
{
public: }; class BenzSteering
{
public:
BenzSteering()
{
cout << "I am BenzSteering" << endl;
}
}; class BMWSteering
{
public:
BMWSteering()
{
cout << "I am BMWSteering" << endl;
}
}; class AbstractFactory
{
public:
virtual void CreateWheel(); // No implement in virtual base class
virtual void CreateSteering(); // No implement in virtual base class
}; class BenzFactory
{
public:
virtual void CreateWheel()
{
new BenzWheel();
}
virtual void CreateSteering()
{
new BenzSteering();
}
}; class BMWFactory
{
public:
virtual void CreateWheel()
{
new BMWWheel();
}
virtual void CreateSteering()
{
new BMWSteering();
}
}; void CreateCar(AbstractFactory& factory)
{
factory.CreateSteering();
factory.CreateWheel();
} int _tmain(int argc, _TCHAR* argv[])
{
// I want a BMW car
BMWFactory factory;
CreateCar((AbstractFactory&)factory);
// I want a Benz car
//BenzFactory factory;
//CreateCar((AbstractFactory&)factory);
return ;
}

如果你想要一辆Benz car,将main()中的注释代码放开就可以了。

顺便说一下,上面代码中,CreateCar并不是Factory类的成员函数;这貌似不符合现实世界汽车厂的一贯做法。不过我们的代码例子主要为了演示Abstract Factory模式,而这种模式主要关心的是“产品部件生产”的抽象,而不关心“产品组装”的抽象,所以代码和现实的这点区别就忽略吧。或者想一想书中不同风格窗口的那个例子:不同风格窗口的组装是应用程序的事情,而不是Widget类库的事情。

设计模式初学者笔记:Abstract Factory模式的更多相关文章

  1. 设计模式初学者笔记:Factory Method模式

    如果要选择一种最多人熟悉的Factory Method模式的具体应用,那么就应该是MFC的App/Doc架构了.Factory Method主要在类框架中使用,以解决以下问题:框架必须实例化类,但框架 ...

  2. 设计模式初学者笔记:Builder模式

    [作者:byeyear    Email:byeyear@hotmail.com    首发:cnblogs    转载请注明] 在本文的开头,先森森的鄙视下自己……将Builder模式反反复复读了七 ...

  3. 设计模式学习笔记 1.factory 模式

    Factory 模式 用户不关心工厂的具体类型,只知道这是一个工厂就行. 通过工厂的实现推迟到子类里面去来确定工厂的具体类型. 工厂的具体类型来确定生产的具体产品. 同时用户不关心这是一个什么样子的产 ...

  4. 设计模式02: Abstract Factory 抽象工厂(创建型模式)

    Abstract Factory 抽象工厂(创建型模式) 常见的对象创建方法:    //创建一个Road对象    Road road=new Road();    new的问题:    -实现依赖 ...

  5. c++ 设计模式9 (Abstract Factory 抽象工厂模式)

    5.2 抽象工厂模式 动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作:同时,由于需求的变化,往往存在更多系列对象的创建工作. 代码示例: 实现利用数据库的业务逻辑,支持多数据库(Sq ...

  6. 设计模式(3)-对象创建型模式-Abstract Factory模式

    1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: •  一个系统要独立于它的产品的创建. ...

  7. 设计模式 - Abstract Factory模式(abstract factory pattern) 详细说明

    Abstract Factory模式(abstract factory pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/ ...

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

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

  9. Abstract Factory模式的几个要点

    1.如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式.这时候使用简单的静态工厂完全可以.2.“系列对象”指的是这些对象之间有相互依赖.或作用的关系3.Abs ...

随机推荐

  1. 自己写的一个delphi正整数快速排序

    type   TIntArr= array of word; procedure MyQSort(var arr: TIntArr; low: word; high: word); //word可以改 ...

  2. numpy 小示例

    import numpy as np 生成 3*4 的由  0 组成的二维数组 >>> np.zeros((3,4)) array([[0., 0., 0., 0.], [0., 0 ...

  3. bacula备份终端操作bconsole指令

    1.list命令列出各种备份状态信息   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 list Jobs     #列出所有备份记录状态 list jobid= ...

  4. mybatis左连接需要输出左表的指定内容与筛选

    SELECT rpl.ID, rpl.DID, rpl.TRADE_TYPE, rpl.TRADE_TIME, rpl.CALL_TIME, rpl.TRADE_ADDR, rpl.RECEIVE_P ...

  5. 建立自己的Servlet--成功

    1--用记事本新建一个servlet程序,文件名为HelloWorld.java,文件内容如下: import java.io.*; import javax.servlet.*; import ja ...

  6. HAWQ + MADlib 玩转数据挖掘之(六)——主成分分析与主成分投影

    一.主成分分析(Principal Component Analysis,PCA)简介 在数据挖掘中经常会遇到多个变量的问题,而且在多数情况下,多个变量之间常常存在一定的相关性.例如,网站的" ...

  7. proxool配置及测试(数据库用的MySQL)

    Proxool连接池设置   Proxool连接池是sourceforge下的一个开源项目,这个项目提供一个健壮.易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况. ...

  8. magento的布局文件之谜

    magento的布局文件layout.xml文件详解 解析顺序 布局xml文件一般位于app/design/{area}/{package}/{theme}/layout/目录下.Layout文件一般 ...

  9. Sublime配置VI插件后 快捷键总结

    Vi编辑器快捷键  命令行模式:  yy 复制当前行  yy5 复制向下5行  p 粘贴(注意粘贴到最后时候留一个换行符)  p5 粘贴5次  dd 删除一行,剪切一行  G 最后一行  1G 第一行 ...

  10. HTML标签 select 里 动态添加option

    HTML标签 select 里 动态添加option: ☆ var today = new Date(); var yearNow = today.getFullYear(); var optiong ...