生成器模式:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
结构图
Builder是为创建一个Product对象的各个部件指定的抽象接口。ConcreteBuilder是具体生成者,实现Builder接口,构造和装配各个部件。Product是产品角色,Director是指挥者,它是构建一个使用Builder接口的对象。主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临复杂的变化。
生成器模式的好处就是使得生成代码与表示代码分离,由于生成者隐藏了该产品如何组装,所以若要改变一个产品的内部表示,只需要再定义一个具体的生成者就可以了。
生成器模式基本代码
- // Builder.cpp : Defines the entry point for the console application.
- //
- #include <iostream>
- #include <string>
- #include <list>
- #include <algorithm>
- using namespace std;
- void Print(string &str)
- {
- cout << str << endl;
- }
- class Product
- {
- public:
- void Add(string part)
- {
- parts.push_back(part);
- }
- void Show()
- {
- cout << "/n产品 创建 ----" << endl;
- for_each(parts.begin(),parts.end(),Print);
- }
- private:
- list<string> parts;
- };
- class Builder
- {
- public:
- virtual void BuildPartA() = 0;
- virtual void BuildPartB() = 0;
- virtual Product GetResult() = 0;
- };
- class Director
- {
- public:
- Director(Builder* builder)
- {
- builder->BuildPartA();
- builder->BuildPartB();
- }
- };
- class ConcreteBuilder1 : public Builder
- {
- private:
- Product product;
- public:
- virtual void BuildPartA()
- {
- product.Add("部件A");
- }
- virtual void BuildPartB()
- {
- product.Add("部件B");
- }
- virtual Product GetResult()
- {
- return product;
- }
- };
- class ConcreteBuilder2 : public Builder
- {
- private:
- Product product;
- public:
- virtual void BuildPartA()
- {
- product.Add("部件X");
- }
- virtual void BuildPartB()
- {
- product.Add("部件Y");
- }
- virtual Product GetResult()
- {
- return product;
- }
- };
- int main()
- {
- Builder *b1 = new ConcreteBuilder1();
- Builder *b2 = new ConcreteBuilder2();
- Director director1(b1);
- Product p1 = b1->GetResult();
- p1.Show();
- Director director2(b2);
- Product p2 = b2->GetResult();
- p2.Show();
- return 0;
- }
生成器模式的具体实现
[画卡通小人的实例]
- // CreatePerson.cpp : Defines the entry point for the application.
- //
- #include <windows.h>
- #pragma comment(linker,"/subsystem:windows")
- #define MAX_LOADSTRING 100
- #define IDC_CREATEPERSON "CREATEPERSON"
- //生成器模式
- class Person
- {
- public:
- virtual void BuilderHead(int X1, int Y1, int X2, int Y2)
- {
- Head[0] = X1; Head[1] = Y1; Head[2] = X2; Head[3] = Y2;
- }
- virtual void BuilderBody(int X1, int Y1, int X2, int Y2)
- {
- Body[0] = X1; Body[1] = Y1; Body[2] = X2; Body[3] = Y2;
- }
- virtual void BuilderLeftArm(int X1, int Y1, int X2, int Y2)
- {
- LfAm[0] = X1; LfAm[1] = Y1; LfAm[2] = X2; LfAm[3] = Y2;
- }
- virtual void BuilderRightArm(int X1, int Y1, int X2, int Y2)
- {
- RtAm[0] = X1; RtAm[1] = Y1; RtAm[2] = X2; RtAm[3] = Y2;
- }
- virtual void BuilderLeftLeg(int X1, int Y1, int X2, int Y2)
- {
- LfLg[0] = X1; LfLg[1] = Y1; LfLg[2] = X2; LfLg[3] = Y2;
- }
- virtual void BuilderRightLeg(int X1, int Y1, int X2, int Y2)
- {
- RtLg[0] = X1; RtLg[1] = Y1; RtLg[2] = X2; RtLg[3] = Y2;
- }
- void ShowPerson(HDC hDC)
- {
- Ellipse (hDC, Head[0], Head[1], Head[2], Head[3]);
- Rectangle(hDC, Body[0], Body[1], Body[2], Body[3]);
- MoveToEx (hDC, LfAm[0], LfAm[1], NULL); LineTo(hDC, LfAm[2], LfAm[3]);
- MoveToEx (hDC, RtAm[0], RtAm[1], NULL); LineTo(hDC, RtAm[2], RtAm[3]);
- MoveToEx (hDC, LfLg[0], LfLg[1], NULL); LineTo(hDC, LfLg[2], LfLg[3]);
- MoveToEx (hDC, RtLg[0], RtLg[1], NULL); LineTo(hDC, RtLg[2], RtLg[3]);
- }
- private:
- int Head[4],Body[4],LfAm[4],RtAm[4],LfLg[4],RtLg[4];
- };
- class Builder
- {
- public:
- virtual void BuilderA() = 0;
- virtual void BuilderB() = 0;
- virtual void BuilderC() = 0;
- virtual void BuilderD() = 0;
- virtual void BuilderE() = 0;
- virtual void BuilderF() = 0;
- virtual Person GetPerson() = 0;
- };
- class ConcreteBuilderThin: public Builder
- {
- public:
- void BuilderA()
- {
- Po.BuilderHead(50, 20, 80, 50);
- }
- void BuilderB()
- {
- Po.BuilderBody(60, 50, 70, 100);
- }
- void BuilderC()
- {
- Po.BuilderLeftArm(60, 50, 40, 100);
- }
- void BuilderD()
- {
- Po.BuilderRightArm(70, 50, 90, 100);
- }
- void BuilderE()
- {
- Po.BuilderLeftLeg(60, 100, 45, 150);
- }
- void BuilderF()
- {
- Po.BuilderRightLeg(70, 100, 85, 150);
- }
- Person GetPerson()
- {
- return Po;
- }
- private:
- Person Po;
- };
- class ConcreteBuilderFat: public Builder
- {
- public:
- void BuilderA()
- {
- Po.BuilderHead(150, 20, 180, 50);
- }
- void BuilderB()
- {
- Po.BuilderBody(150, 50, 180, 100);
- }
- void BuilderC()
- {
- Po.BuilderLeftArm(150, 50, 130, 100);
- }
- void BuilderD()
- {
- Po.BuilderRightArm(180, 50, 200, 100);
- }
- void BuilderE()
- {
- Po.BuilderLeftLeg(160, 100, 145, 150);
- }
- void BuilderF()
- {
- Po.BuilderRightLeg(170, 100, 185, 150);
- }
- Person GetPerson()
- {
- return Po;
- }
- private:
- Person Po;
- };
- class Director
- {
- public:
- void CreatePerson(Builder * builder)
- {
- builder->BuilderA();
- builder->BuilderB();
- builder->BuilderC();
- builder->BuilderD();
- builder->BuilderE();
- builder->BuilderF();
- }
- };
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
- // Foward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- // TODO: Place code here.
- MSG msg;
- // Initialize global strings
- strcpy(szTitle, "CreatePerson");
- strcpy(szWindowClass, "CREATEPERSON");
- MyRegisterClass(hInstance);
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, NULL);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = (LPCSTR)IDC_CREATEPERSON;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, NULL);
- return RegisterClassEx(&wcex);
- }
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // Store instance handle in our global variable
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- PAINTSTRUCT ps;
- HDC hdc;
- HBRUSH hBrush;
- switch (message)
- {
- case WM_COMMAND:
- break;
- case WM_PAINT:
- {
- hdc = BeginPaint(hWnd, &ps);
- hBrush = CreateSolidBrush(RGB(0,255,0));
- SelectObject(hdc, hBrush);
- // TODO: Add any drawing code here...
- Builder * bt = new ConcreteBuilderThin();
- Builder * bf = new ConcreteBuilderFat();
- Director dr;
- dr.CreatePerson(bt);
- dr.CreatePerson(bf);
- Person Po1 = bt->GetPerson();
- Po1.ShowPerson(hdc);
- Person Po2 = bf->GetPerson();
- Po2.ShowPerson(hdc);
- delete bt;
- delete bf;
- DeleteObject(hBrush);
- EndPaint(hWnd, &ps);
- }
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
读《大话设计模式》---生成器模式(Builder)