大话设计模式--建造者模式 Builder -- C++实现实例
1. 建造者模式,将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。
用户只需要指定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了。
关键类Director,用它来控制建造过程,用它来隔离用户与建造过程的关联。
适用场合主要是用于创建一些复杂的对象, 这些对象内部的构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
在创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式适用的模式。
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
实例骨架:
product.h product.cpp
#ifndef PRODUCT_H #define PRODUCT_H #include <iostream> #include <list> #include <string> using namespace std; class Product { public: Product(); void addPart(string part); void show(); private: list<string> *parts; }; #endif // PRODUCT_H
#include "product.h" Product::Product() { parts = new list<string>; } void Product::addPart(string part) { parts->push_back(part); } void Product::show() { for(list<string>::iterator i=parts->begin(); i!=parts->end(); i++) cout << "part: " << *i << endl; }
builder.h builder.cpp
#ifndef BUILDER_H #define BUILDER_H #include "product.h" class Builder { public: Builder(); void virtual builderPartA()=0; void virtual builderPartB()=0; virtual Product* getResult()=0; }; #endif // BUILDER_H
#include "builder.h" Builder::Builder() { }
concretebuilder1.h concretebuilder1.cpp
#ifndef CONCRETEBUILDER1_H #define CONCRETEBUILDER1_H #include "builder.h" class ConcreteBuilder1 : public Builder { public: ConcreteBuilder1(); ~ConcreteBuilder1(); void builderPartA(); void builderPartB(); Product* getResult(); private: Product *product; }; #endif // CONCRETEBUILDER1_H
#include "concretebuilder1.h" ConcreteBuilder1::ConcreteBuilder1() { product = new Product(); } ConcreteBuilder1::~ConcreteBuilder1() { delete product; } void ConcreteBuilder1::builderPartA() { product->addPart("ConcreteBuilder1 A"); } void ConcreteBuilder1::builderPartB() { product->addPart("ConcreteBuilder1 B"); } Product* ConcreteBuilder1::getResult() { return product; }
concretebuilder2.h concretebuilder2.cpp
#ifndef CONCRETEBUILDER2_H #define CONCRETEBUILDER2_H #include "builder.h" class ConcreteBuilder2 : public Builder { public: ConcreteBuilder2(); ~ConcreteBuilder2(); void builderPartA(); void builderPartB(); Product* getResult(); private: Product *product; }; #endif // CONCRETEBUILDER2_H
#include "concretebuilder2.h" ConcreteBuilder2::ConcreteBuilder2() { product = new Product(); } ConcreteBuilder2::~ConcreteBuilder2() { delete product; } void ConcreteBuilder2::builderPartA() { product->addPart("ConcreteBuilder2 A"); } void ConcreteBuilder2::builderPartB() { product->addPart("ConcreteBuilder2 B"); } Product* ConcreteBuilder2::getResult() { return product; }
director.h director.cpp
#ifndef DIRECTOR_H #define DIRECTOR_H #include "builder.h" class Director { public: Director(); void construct(Builder *builder); }; #endif // DIRECTOR_H
#include "director.h" Director::Director() { } void Director::construct(Builder *builder) { builder->builderPartA(); builder->builderPartB(); }
main.cpp
#include <iostream> #include "product.h" #include "concretebuilder1.h" #include "concretebuilder2.h" #include "director.h" using namespace std; int main() { cout << "Builder test !" << endl; Product *product = new Product(); ConcreteBuilder1 build1; Director director; director.construct(&build1); product = build1.getResult(); product->show(); ConcreteBuilder2 build2; director.construct(&build2); product = build2.getResult(); product->show(); delete product; return 0; }