首先啰嗦下创建迷宫所用的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. SQL*Loader 详解

    在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中2. 建立数据库间的 ...

  2. poj2892

    题解: 答案=后缀-前缀-1 如果被轰了,那么就时0 在一开始加入0,n+1,保证有前缀后缀 代码: #include<cstdio> #include<cmath> #inc ...

  3. DBLookupComboBox 的初始值

    http://www.yourdelphi.com/topic_234544_e6b7.htm 试下在form的oncreate中加入 dblookupcombobox1.keyvalue:=tabl ...

  4. PHP excel reader , excel时间转成php时间格式

    最近,在做一个导入功能,在系统中使用PHPExcel类库,读取上传的Excel文件,然后进行字段映射,最后将Excel内的数据导入到系统中.其中,关于日期格式的导入,使我犯了难. 首先,如何导入日期, ...

  5. 《Python》 基础数据类型补充和深浅copy

    一.基础数据类型的补充 元组: 如果元组中只有一个数据,且没有逗号,则该‘元组’数据类型与里面的数据类型一致 列表: 列表之间可加不可减,可跟数字相乘 l1=['wang','rui'] l2=['c ...

  6. Java虚拟机运行时数据区

    运行时数据区程序计数器Java虚拟机栈本地方法栈Java堆(GC堆)方法区运行时常量池 运行时数据区 Java虚拟机在运行Java程序时,会将它所管理的内存划分为若干个内存区域.这些数据区域有各自的用 ...

  7. Jmeter BeanShell 从数据库中获取数据并创建一个requesBody

    一.前言 在测试接口的时候常常会使用到数据库中的数据,当要使用大量的数据时,仅仅使用数据库查询是不够的.还需要使用自动化让操作更简便. 下面以一个简单的例子阐述一下如何使用beanShell让代码更简 ...

  8. windows与Linux实现文件传输Winscp工具的使用

    WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端.同时支持SCP协议.它的主要功能就是在本地与远程计算机间安全的复制文件..winscp也可以链接其他系统,比如linux系统 ...

  9. 使用Socket的简单Web服务器

    Socket类在System.Net.Sockets命名空间 常用的操作 Bind:绑定一个本地的终结点 Listen:进入监听状态,并设置等待队列 Accept:等待一个新连接,当连接到达时,返回一 ...

  10. 2018-2019-2 网络对抗技术 20165202 Exp1 PC平台逆向破解

    一.基础知识 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码. NOP指令为空指令,当运行该指令时CPU不做任何事情,但是会占用一个指令的时间,当指令间需要有延时,可以插入NOP指令 ...