首先啰嗦下创建迷宫所用的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. bzoj1008

    题解: 要求有几种方案可以越狱,可以用总方案-不会越狱的方案 那么总方案就是m^n 那么考虑不会越狱的方案 显然第一个人有m中,后面都是m-1中(和前一个不一样) 答案就是m^n-m*(m-1)^(n ...

  2. css 让div 置于最顶层而不被其他东西挡住

    今天遇到自己写的div被其他东西给挡住了,需要设置一个属性就成功了 设置:z-index:值:比如 z-index:999. 若值设置为为-1,代表为最底层. div的图层由div的style中的z- ...

  3. 读书笔记 C# Lookup<TKey,TElement>和ToLookup方法的浅析

    Lookup<TKey,TElement>类型对象和分组是一样的,就好比使用Linq的group关键字后所查询出来的结果,使用foreach的时候,都可以用IGrouping<TKe ...

  4. L1-026 I Love GPLT

    这道超级简单的题目没有任何输入. 你只需要把这句很重要的话 —— “I Love GPLT”——竖着输出就可以了. 所谓“竖着输出”,是指每个字符占一行(包括空格),即每行只能有1个字符和回车. 输入 ...

  5. Python 编程核心知识体系-文件对象|错误处理(四)

    错误处理 文件对象

  6. Translate Exercises(3) 科技英语翻译

    [1] CMOS logic is a newer technology, based on the use of complementary MOS transistorsto perform lo ...

  7. JVM自动内存管理:对象判定和回收算法

    可回收对象的判断方法 1.引用计数算法 2.可达性分析算法 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是 ...

  8. Android Mms之:深入MMS支持

    Composing and editing MMS在Android Mms应用里面的具体实现形式,或数据结构是SlideshowModel,它是一个每个节点为SlideModel的ArrayList, ...

  9. Python 字典的遍历

    dic = {"赵四":"刘晓光", "刘能":"王晓利", "王木生":"范伟" ...

  10. promise的生命周期

    每个promise都会经历一个短暂的生命周期: 先是处于进行中(pending)状态,此时操作并未完成,所以他也是未处理的(unsettled): 一旦异步惭怍执行结束,promise则 变为已处理( ...