建造者模式主要为解决一个问题,当构造一个对象本身变得复杂时,如果又有另一个类似的对象需要构造,难道需要程序员自己清楚的记住应该先干嘛后干嘛然后获得一个对象吗?能不能把构造流程标准化?标准化的流程顺带解决了另一个问题,它可以防止未构造完成的”半成品”流入客户手中产生未知后果
比如我们需要建造一座房子,一定是从下往上建造,依次完成地面,墙体,以及屋顶。无论是木屋还是石头屋都要遵守这个流程,先设计一个抽象的Builder类,它有建造地面,墙体,屋顶的方法,并提供一个最后的获取产品的接口build,用WoodHouseBuilder和StoneHouseBuilder来继承它,分别实现建造各个组件的方法,最后我们设计一个director,让他指导Builder将建造流程标准化(先建造地面,然后墙,然后屋顶),最后我们即可从Builder的build接口获取到一个成品房子,绝对不会拿到一个半成品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <iostream> #include <string>
class building { public: void setFloor(std::string floor) { m_floor = floor; } void setwall(std::string wall) { m_wall = wall; } void setroof(std::string roof) { m_roof = roof; }
void show() { std::cout << m_floor << "+" << m_wall << "+" << m_roof << std::endl; } private: std::string m_floor; std::string m_wall; std::string m_roof; };
class Builder { public: virtual Builder& buildFloor() = 0; virtual Builder& buildWall() = 0; virtual Builder& buildRoof() = 0; virtual building* build() = 0; virtual ~Builder() {};
};
class WoodHouseBuilder : public Builder { public: Builder& buildFloor() override { m_house = new building(); m_house->setFloor("木地板"); return *this; } Builder& buildWall() override { m_house->setwall("木头墙"); return *this; } Builder& buildRoof() override { m_house->setroof("茅草屋顶"); return *this; }
building* build() override { return m_house; } private: building *m_house; }; class StoneHouseBuilder : public Builder { public: Builder& buildFloor() override { m_house = new building(); m_house->setFloor("大理石"); return *this; } Builder& buildWall() override { m_house->setwall("石头墙"); return *this; } Builder& buildRoof() override { m_house->setroof("石头屋顶"); return *this; }
building* build() override { return m_house; } private: building *m_house; };
class director { public: void oversee(Builder *b) { b->buildFloor().buildWall().buildRoof(); } };
int main() { director d; StoneHouseBuilder s;
d.oversee(&s);
building *myhouse = s.build();
myhouse->show();
delete myhouse;
return 0; }
|