首先啰嗦下创建迷宫所用的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. QRCodeHelper 二维码生成

    QRCodeHelper 二维码生成 using System; using System.Drawing; using ThoughtWorks.QRCode.Codec; using System ...

  2. Oracle 11g 在audit_file_dest目录下产生大量的aud文件

    一.adump目录数据暴增现象 发现某台数据库服务器的根目录的使用率在暴涨,发现Oracle数据库的adump目录,每秒生成一个dump文件.数据库并未开通审计外部记录.为什么adump目录会生成那么 ...

  3. 2.3 C++类的信息隐藏机制 -- 封装

    参考:http://www.weixueyuan.net/view/6335.html 总结: private.protected和public  限制类中声明的变量和函数在外部的访问权限. 声明为p ...

  4. 用MyEclipse JPA创建项目(四)

    MyEclipse 3.15 Style——在线购买低至75折!火爆开抢>> [MyEclipse最新版下载] 本教程介绍了MyEclipse中的一些基于PA的功能. 阅读本教程时,了解J ...

  5. anu - reactShime

    import { Component } from "./Component"; import { options } from "./util"; impor ...

  6. django2 删除图片或其他

    首先从数据库中获取图片的名称,然后拼接图片的物理地址,最后就是删除. # 物理删除图片 d = os.path.dirname(os.path.dirname(os.path.abspath(__fi ...

  7. 5.1 socket编程、简单并发服务器

    什么是socket? socket可以看成是用户进程与内核网络协议栈的编程接口.是一套api函数. socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机间的进程间通信. 工业上使用的为t ...

  8. 【计算机视觉】交并比IOU概念理解

    前言 交并比IOU(Intersection over Union)是一种测量在特定数据集中检测相应物体准确度的一个标准. 图示 很简单,IoU相当于两个区域重叠的部分除以两个区域的集合部分得出的结果 ...

  9. linux-performance

    1. top 2. cat /proc/meminfo nvidia@tegra-ubuntu:~/zrj/laneseg_TRT$ cat /proc/meminfo MemTotal: kB Me ...

  10. 《DSP using MATLAB》Problem 3.17

    用差分方程两边进行z变换,再变量带换得到频率响应函数(或转移函数,即LTI系统脉冲响应的DTFT). 代码: %% ------------------------------------------ ...