现在的位置: 首页 > 综合 > 正文

读《大话设计模式》---生成器模式(Builder)

2012年05月20日 ⁄ 综合 ⁄ 共 8389字 ⁄ 字号 评论关闭

生成器模式:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

 

结构图

 

Builder是为创建一个Product对象的各个部件指定的抽象接口。ConcreteBuilder是具体生成者,实现Builder接口,构造和装配各个部件。Product是产品角色,Director是指挥者,它是构建一个使用Builder接口的对象。主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临复杂的变化。

生成器模式的好处就是使得生成代码与表示代码分离,由于生成者隐藏了该产品如何组装,所以若要改变一个产品的内部表示,只需要再定义一个具体的生成者就可以了。

 

生成器模式基本代码

  1. // Builder.cpp : Defines the entry point for the console application.
  2. //
  3. #include <iostream>
  4. #include <string>
  5. #include <list>
  6. #include <algorithm>
  7. using namespace std;
  8. void Print(string &str)
  9. {
  10.     cout << str << endl;
  11. }
  12. class Product
  13. {
  14. public:
  15.     void Add(string part)
  16.     {
  17.         parts.push_back(part);
  18.     }
  19.     void Show()
  20.     {
  21.         cout << "/n产品 创建 ----" << endl;
  22.         for_each(parts.begin(),parts.end(),Print);
  23.     }
  24. private:
  25.     list<string> parts;
  26. };
  27. class Builder
  28. {
  29. public:
  30.     virtual void BuildPartA() = 0;
  31.     virtual void BuildPartB() = 0;
  32.     virtual Product GetResult() = 0;
  33. };
  34. class Director
  35. {
  36. public:
  37.     Director(Builder* builder)
  38.     {
  39.         builder->BuildPartA();
  40.         builder->BuildPartB();
  41.     }
  42. };
  43. class ConcreteBuilder1 : public Builder
  44. {
  45. private:
  46.     Product product;
  47.     
  48. public:
  49.     virtual void BuildPartA()
  50.     {
  51.         product.Add("部件A");
  52.     }
  53.     
  54.     virtual void BuildPartB()
  55.     {
  56.         product.Add("部件B");
  57.     }
  58.     
  59.     virtual Product GetResult()
  60.     {
  61.         return product;
  62.     }
  63. };
  64. class ConcreteBuilder2 : public Builder
  65. {
  66. private:
  67.     Product product;
  68. public:
  69.     virtual void BuildPartA()
  70.     {
  71.         product.Add("部件X");
  72.     }
  73.     
  74.     virtual void BuildPartB()
  75.     {
  76.         product.Add("部件Y");
  77.     }
  78.     
  79.     virtual Product GetResult()
  80.     {
  81.         return product;
  82.     }
  83. };
  84. int main()
  85. {
  86.     Builder *b1 = new ConcreteBuilder1();
  87.     Builder *b2 = new ConcreteBuilder2();
  88.     
  89.     Director director1(b1);
  90.     Product p1 = b1->GetResult();
  91.     p1.Show();
  92.     
  93.     Director director2(b2);
  94.     Product p2 = b2->GetResult();
  95.     p2.Show();
  96.     
  97.     return 0;
  98. }

生成器模式的具体实现

[画卡通小人的实例]

  1. // CreatePerson.cpp : Defines the entry point for the application.
  2. //
  3. #include <windows.h>
  4. #pragma comment(linker,"/subsystem:windows")
  5. #define MAX_LOADSTRING 100
  6. #define IDC_CREATEPERSON   "CREATEPERSON"
  7. //生成器模式
  8. class Person
  9. {
  10. public:
  11.     virtual void BuilderHead(int X1, int Y1, int X2, int Y2)
  12.     {
  13.         Head[0] = X1; Head[1] = Y1; Head[2] = X2; Head[3] = Y2;
  14.     }
  15.     virtual void BuilderBody(int X1, int Y1, int X2, int Y2)
  16.     {
  17.         Body[0] = X1; Body[1] = Y1; Body[2] = X2; Body[3] = Y2;
  18.     }
  19.     virtual void BuilderLeftArm(int X1, int Y1, int X2, int Y2)
  20.     {
  21.         LfAm[0] = X1; LfAm[1] = Y1; LfAm[2] = X2; LfAm[3] = Y2;
  22.     }
  23.     virtual void BuilderRightArm(int X1, int Y1, int X2, int Y2)
  24.     {
  25.         RtAm[0] = X1; RtAm[1] = Y1; RtAm[2] = X2; RtAm[3] = Y2;
  26.     }
  27.     virtual void BuilderLeftLeg(int X1, int Y1, int X2, int Y2)
  28.     {
  29.         LfLg[0] = X1; LfLg[1] = Y1; LfLg[2] = X2; LfLg[3] = Y2;
  30.     }
  31.     virtual void BuilderRightLeg(int X1, int Y1, int X2, int Y2)
  32.     {
  33.         RtLg[0] = X1; RtLg[1] = Y1; RtLg[2] = X2; RtLg[3] = Y2;
  34.     }
  35.     void ShowPerson(HDC hDC)
  36.     {
  37.         Ellipse  (hDC, Head[0], Head[1], Head[2], Head[3]);
  38.         Rectangle(hDC, Body[0], Body[1], Body[2], Body[3]);
  39.         MoveToEx (hDC, LfAm[0], LfAm[1], NULL);   LineTo(hDC, LfAm[2], LfAm[3]);
  40.         MoveToEx (hDC, RtAm[0], RtAm[1], NULL);   LineTo(hDC, RtAm[2], RtAm[3]);
  41.         MoveToEx (hDC, LfLg[0], LfLg[1], NULL);   LineTo(hDC, LfLg[2], LfLg[3]);
  42.         MoveToEx (hDC, RtLg[0], RtLg[1], NULL);   LineTo(hDC, RtLg[2], RtLg[3]);
  43.     }
  44. private:
  45.     int Head[4],Body[4],LfAm[4],RtAm[4],LfLg[4],RtLg[4];
  46. };
  47. class Builder
  48. {
  49. public:
  50.     virtual void BuilderA() = 0;
  51.     virtual void BuilderB() = 0;
  52.     virtual void BuilderC() = 0;
  53.     virtual void BuilderD() = 0;
  54.     virtual void BuilderE() = 0;
  55.     virtual void BuilderF() = 0;
  56.     virtual Person GetPerson() = 0;
  57. };
  58. class ConcreteBuilderThin: public Builder
  59. {
  60. public:
  61.     void BuilderA()
  62.     {
  63.         Po.BuilderHead(50, 20, 80, 50);
  64.     }
  65.     void BuilderB()
  66.     {
  67.         Po.BuilderBody(60, 50, 70, 100);
  68.     }
  69.     void BuilderC()
  70.     {
  71.         Po.BuilderLeftArm(60, 50, 40, 100);
  72.     }
  73.     void BuilderD()
  74.     {
  75.         Po.BuilderRightArm(70, 50, 90, 100);
  76.     }
  77.     void BuilderE()
  78.     {
  79.         Po.BuilderLeftLeg(60, 100, 45, 150);
  80.     }
  81.     void BuilderF()
  82.     {
  83.         Po.BuilderRightLeg(70, 100, 85, 150);
  84.     }
  85.     Person GetPerson()
  86.     {
  87.         return Po;
  88.     }
  89. private:
  90.     Person Po;
  91. };
  92. class ConcreteBuilderFat: public Builder
  93. {
  94. public:
  95.     void BuilderA()
  96.     {
  97.         Po.BuilderHead(150, 20, 180, 50);
  98.     }
  99.     void BuilderB()
  100.     {
  101.         Po.BuilderBody(150, 50, 180, 100);
  102.     }
  103.     void BuilderC()
  104.     {
  105.         Po.BuilderLeftArm(150, 50, 130, 100);
  106.     }
  107.     void BuilderD()
  108.     {
  109.         Po.BuilderRightArm(180, 50, 200, 100);
  110.     }
  111.     void BuilderE()
  112.     {
  113.         Po.BuilderLeftLeg(160, 100, 145, 150);
  114.     }
  115.     void BuilderF()
  116.     {
  117.         Po.BuilderRightLeg(170, 100, 185, 150);
  118.     }
  119.     Person GetPerson()
  120.     {
  121.         return Po;
  122.     }
  123. private:
  124.     Person Po;
  125. };
  126. class Director
  127. {
  128. public:
  129.     void CreatePerson(Builder * builder)
  130.     {
  131.         builder->BuilderA();
  132.         builder->BuilderB();
  133.         builder->BuilderC();
  134.         builder->BuilderD();
  135.         builder->BuilderE();
  136.         builder->BuilderF();
  137.     }
  138. };
  139. // Global Variables:
  140. HINSTANCE hInst;                                // current instance
  141. TCHAR szTitle[MAX_LOADSTRING];                              // The title bar text
  142. TCHAR szWindowClass[MAX_LOADSTRING];                                // The title bar text
  143. // Foward declarations of functions included in this code module:
  144. ATOM                MyRegisterClass(HINSTANCE hInstance);
  145. BOOL                InitInstance(HINSTANCEint);
  146. LRESULT CALLBACK    WndProc(HWNDUINTWPARAMLPARAM);
  147. LRESULT CALLBACK    About(HWNDUINTWPARAMLPARAM);
  148. int APIENTRY WinMain(HINSTANCE hInstance,
  149.                      HINSTANCE hPrevInstance,
  150.                      LPSTR     lpCmdLine,
  151.                      int       nCmdShow)
  152. {
  153.     // TODO: Place code here.
  154.     MSG msg;
  155.     // Initialize global strings
  156.     strcpy(szTitle, "CreatePerson");
  157.     strcpy(szWindowClass, "CREATEPERSON");
  158.     MyRegisterClass(hInstance);
  159.     // Perform application initialization:
  160.     if (!InitInstance (hInstance, nCmdShow)) 
  161.     {
  162.         return FALSE;
  163.     }
  164.     // Main message loop:
  165.     while (GetMessage(&msg, NULL, 0, 0)) 
  166.     {
  167.         TranslateMessage(&msg);
  168.         DispatchMessage(&msg);
  169.     }
  170.     return msg.wParam;
  171. }
  172. ATOM MyRegisterClass(HINSTANCE hInstance)
  173. {
  174.     WNDCLASSEX wcex;
  175.     wcex.cbSize = sizeof(WNDCLASSEX); 
  176.     wcex.style          = CS_HREDRAW | CS_VREDRAW;
  177.     wcex.lpfnWndProc    = (WNDPROC)WndProc;
  178.     wcex.cbClsExtra     = 0;
  179.     wcex.cbWndExtra     = 0;
  180.     wcex.hInstance      = hInstance;
  181.     wcex.hIcon          = LoadIcon(hInstance, NULL);
  182.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  183.     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  184.     wcex.lpszMenuName   = (LPCSTR)IDC_CREATEPERSON;
  185.     wcex.lpszClassName  = szWindowClass;
  186.     wcex.hIconSm        = LoadIcon(wcex.hInstance, NULL);
  187.     return RegisterClassEx(&wcex);
  188. }
  189. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  190. {
  191.    HWND hWnd;
  192.    hInst = hInstance; // Store instance handle in our global variable
  193.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  194.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  195.    if (!hWnd)
  196.    {
  197.       return FALSE;
  198.    }
  199.    ShowWindow(hWnd, nCmdShow);
  200.    UpdateWindow(hWnd);
  201.    return TRUE;
  202. }
  203. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  204. {
  205.     PAINTSTRUCT ps;
  206.     HDC hdc;
  207.     HBRUSH hBrush;
  208.     switch (message) 
  209.     {
  210.         case WM_COMMAND:
  211.             break;
  212.         case WM_PAINT:
  213.             {
  214.                 hdc = BeginPaint(hWnd, &ps);
  215.                 hBrush = CreateSolidBrush(RGB(0,255,0));
  216.                 SelectObject(hdc, hBrush);
  217.                 // TODO: Add any drawing code here...
  218.                 Builder * bt = new ConcreteBuilderThin();
  219.                 Builder * bf = new ConcreteBuilderFat();
  220.                 
  221.                 Director dr;
  222.                 dr.CreatePerson(bt);
  223.                 dr.CreatePerson(bf);
  224.                 Person Po1 = bt->GetPerson();
  225.                 Po1.ShowPerson(hdc);
  226.                 Person Po2 = bf->GetPerson();
  227.                 Po2.ShowPerson(hdc);
  228.                 delete bt;
  229.                 delete bf;
  230.                 DeleteObject(hBrush);
  231.                 EndPaint(hWnd, &ps);
  232.             }
  233.             break;
  234.         case WM_DESTROY:
  235.             PostQuitMessage(0);
  236.             break;
  237.         default:
  238.             return DefWindowProc(hWnd, message, wParam, lParam);
  239.    }
  240.    return 0;
  241. }

读《大话设计模式》---生成器模式(Builder)

抱歉!评论已关闭.