zoukankan      html  css  js  c++  java
  • 设计模式初学者笔记:Abstract Factory模式

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

    image

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

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

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

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

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

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

          下面是代码:

      1 // 编译环境:VS2008
      2 // AbstractFactory.cpp : 定义控制台应用程序的入口点。
      3 //
      4 
      5 #include "stdafx.h"
      6 #include <iostream>
      7 
      8 using namespace std;
      9 
     10 class AbstractWheel
     11 {
     12 public:
     13     
     14 };
     15 
     16 class BenzWheel : public AbstractWheel
     17 {
     18 public:
     19     BenzWheel()
     20     {
     21         cout << "I am BenzWheel" << endl;
     22     }
     23 };
     24 
     25 class BMWWheel : public AbstractWheel
     26 {
     27 public:
     28     BMWWheel()
     29     {
     30         cout << "I am BMWWheel" << endl;
     31     }
     32 };
     33 
     34 class AbstractSteering
     35 {
     36 public:
     37 
     38 };
     39 
     40 class BenzSteering
     41 {
     42 public:
     43     BenzSteering()
     44     {
     45         cout << "I am BenzSteering" << endl;
     46     }
     47 };
     48 
     49 class BMWSteering
     50 {
     51 public:
     52     BMWSteering()
     53     {
     54         cout << "I am BMWSteering" << endl;
     55     }
     56 };
     57 
     58 class AbstractFactory
     59 {
     60 public:
     61     virtual void CreateWheel();     // No implement in virtual base class
     62     virtual void CreateSteering();  // No implement in virtual base class
     63 };
     64 
     65 class BenzFactory
     66 {
     67 public:
     68     virtual void CreateWheel()
     69     {
     70         new BenzWheel();
     71     }
     72     virtual void CreateSteering()
     73     {
     74         new BenzSteering();
     75     }
     76 };
     77 
     78 class BMWFactory
     79 {
     80 public:
     81     virtual void CreateWheel()
     82     {
     83         new BMWWheel();
     84     }
     85     virtual void CreateSteering()
     86     {
     87         new BMWSteering();
     88     }
     89 };
     90 
     91 void CreateCar(AbstractFactory& factory)
     92 {
     93     factory.CreateSteering();
     94     factory.CreateWheel();
     95 }
     96 
     97 int _tmain(int argc, _TCHAR* argv[])
     98 {
     99     // I want a BMW car
    100     BMWFactory factory;
    101     CreateCar((AbstractFactory&)factory);
    102     // I want a Benz car
    103     //BenzFactory factory;
    104     //CreateCar((AbstractFactory&)factory);
    105     return 0;
    106 }

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

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

  • 相关阅读:
    港股通不得不了解的汇率问题
    Red and Black(红与黑)BFS
    什么时候用DFS,什么时候用BFS?(DFS和BFS的特点和异同)
    (最详细解答) 问题 B: DFS or BFS?
    HDU 2181 哈密顿绕行世界问题 (dfs)
    codeup 算法笔记【递归入门】组合+判断素数
    DFS--基本入门模板 和 例题 (绝对入门) (最全)
    福州大学在线测评系统 FZU 1013 RP Game
    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 C Thinking Bear magic
    ACM 数论-博弈 (比赛用)
  • 原文地址:https://www.cnblogs.com/byeyear/p/3784899.html
Copyright © 2011-2022 走看看