我们之前已经了解了单例模式,工厂模式,今天我们来学习建造者模式
一个例子
假设你是老爹汉堡店的员工,你知道这个店的顾客非常难搞,每个人对汉堡的口味都很挑剔:
如果每个汉堡都是一套标准的流程,没有其他的组合,我们其实可以用工厂模式来解决,但是顾客对于自己的汉堡有自己的想法,每个汉堡做出来都有可能不一样。但是如果我们手动去“构造”汉堡,光汉堡材料的排列组合就让我们头晕的了。所以,我们才有了建造者模式:
什么是建造者模式
建造者模式(Builder Pattern)是一种创建型设计模式,旨在将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
核心思想
建造者模式通过引入一个“建造者”类来逐步构建复杂对象,而不是一次性生成。它将对象的构造过程分解为多个步骤,允许客户端按需选择步骤,从而灵活地创建不同配置的对象。
主要角色
- 产品(Product):最终要构建的复杂对象。
- 抽象建造者(Builder):定义构建产品的各个步骤的接口。
- 具体建造者(Concrete Builder):实现抽象建造者的接口,提供具体的构建步骤,并负责返回最终产品。
- 指挥者(Director):负责调用建造者的步骤,控制构建过程。
优点
- 分离构建与表示:将对象的构建过程与表示分离,使得构建过程更加灵活。
- 易于扩展:新增具体建造者无需修改现有代码,符合开闭原则。
- 精细控制:允许逐步构建对象,精确控制构建过程。
缺点
- 增加复杂性:需要定义多个类,增加了代码的复杂性。
- 适用场景有限:适用于构建复杂对象,简单对象使用该模式可能显得繁琐。
适用场景
- 需要创建的对象具有复杂的内部结构。
- 对象的构建过程需要独立于其组成部分。
- 需要构建的对象有不同的表示形式。
对于汉堡实现建造者模式
class Humburger
{
private:std::string bread;bool lettuce;bool tomato;bool cheese;bool patty;public:void setBread(std::string bread) { this->bread = bread; }void setLettuce(bool lettuce) { this->lettuce = lettuce; }void setTomato(bool tomato) { this->tomato = tomato; }void setCheese(bool cheese) { this->cheese = cheese; }void setPatty(bool patty) { this->patty = patty; }void print() const {std::cout << "Hamburger: " << bread << " with ";if (lettuce) std::cout << "lettuce, ";if (tomato) std::cout << "tomato, ";if (cheese) std::cout << "cheese, ";if (patty) std::cout << "patty, ";std::cout << "prepared.\n";}
};//建造者接口
class HumburBuilder
{
protected:Humburger* hamburger;public:void createNewHumberger(){hamburger = new Humburger();}Humburger* getHamburger() { return hamburger; }virtual void buildBread() = 0;virtual void buildLettuce() = 0;virtual void buildTomato() = 0;virtual void buildCheese() = 0;virtual void buildPatty() = 0;
};// 具体建造者实现
class ConcreteHamburgerBuilder : public HumburBuilder {
public:void buildBread() override { hamburger->setBread("Whole wheat"); }void buildLettuce() override { hamburger->setLettuce(true); }void buildTomato() override { hamburger->setTomato(false); } // 不加番茄void buildCheese() override { hamburger->setCheese(true); }void buildPatty() override { hamburger->setPatty(true); }
};// 指挥者
class Director {
private:HumburBuilder* builder;public:void setBuilder(HumburBuilder* b) { builder = b; }void constructHamburger() {builder->createNewHumberger();builder->buildBread();builder->buildLettuce();builder->buildTomato();builder->buildCheese();builder->buildPatty();}
};int main() {Director director;ConcreteHamburgerBuilder builder;director.setBuilder(&builder);director.constructHamburger();Humburger* hamburger = builder.getHamburger();hamburger->print();delete hamburger;return 0;
}
在这个例子中,我们通过定义一个Hamburger
产品类,一个抽象的HamburgerBuilder
建造者接口,以及具体的ConcreteHamburgerBuilder
建造者实现了建造者模式。Director
类用来指挥建造过程。这样,即使要修改汉堡的配方或者增加新的选项,我们也只需要调整或新增具体的建造者实现即可,不需要改动其他部分的代码,从而提高了代码的可维护性和灵活性。