建造者设计模式
建造者设计模式属于创建型设计模式中的一个。
本文主要记录一下建造者设计模式的简单使用。
建造者设计模式的思想
首先建造者设计模式分为产品,建造者,指挥者三部分。
其中产品是最终呈现的东西;
建造者负责创建这个产品;
指挥者负责调用建造者来创建产品;
实现的过程中,需要考虑产品由哪几部分组成。而建造者需要去创建组成产品的部分,指挥者指挥建造者来执行具体的建造过程。它将复杂对象的构建过程与其表示分离,使得同一个构建过程可以创建不同的表示。
应用场景
1. 需要创建具有多个属性的复杂对象
当对象的构造需要设置大量属性,且这些属性可能有不同的组合时,构建者模式可以简化对象的创建过程。通过链式调用,可以灵活地设置所需的属性,避免构造函数参数过多或重载过多的问题。
2. 对象构造过程需要分步完成
某些对象的构造过程可能需要分步骤进行,例如先初始化必要属性,再设置可选属性。构建者模式允许分步骤构造对象,确保每一步的合法性,最终生成完整的对象。
3. 需要创建不可变对象
构建者模式常用于创建不可变对象(Immutable Object)。通过构建者逐步设置属性,最终调用build()方法生成不可变对象,避免对象在构造过程中被修改。
4. 不同构造方式导致对象差异较大
当同一类的对象可能有多种不同的表示或构造方式时,构建者模式可以封装不同的构造逻辑。例如,一个Pizza对象可能有多种配料组合,构建者可以封装这些组合的构造过程。
5. 避免使用多个构造函数
当类的构造函数参数过多或参数组合复杂时,使用构建者模式可以避免编写多个构造函数或使用冗长的参数列表。构建者模式通过方法名明确参数含义,提高代码可读性。
6. 需要隔离复杂对象的构造与表示
构建者模式将对象的构造过程与对象本身分离,使得相同的构造过程可以创建不同的对象表示。例如,一个文档构建者可以生成HTML或PDF格式的文档,而构造过程保持一致。
实现示例
项目结构

项目代码
main.cpp
cpp
#include <QCoreApplication>
#include "pizza.h"
#include "commander.h"
#include "builder1.h"
#include "builder2.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Commander commander;
Pizza pizza;
Builder1 builder1(&pizza);
commander.makePizza(&builder1);
builder1.getPizza()->displayPakageType();
Builder2 builder2(new Pizza);
commander.makePizza(&builder2);
builder2.getPizza()->displayPakageType();
return a.exec();
}
pizza.h
cpp
#ifndef PIZZA_H
#define PIZZA_H
#include <QString>
class Pizza
{
public:
Pizza();
void setSauce(const QString strSauce);
void setCheese(const QString strCheese);
void setIngredient(const QString strIngredient);
void setBakingDegree(const QString strBakingDegree);
void displayPakageType()const;
private:
QString m_strSauce;//酱料
QString m_strCheese;//奶酪
QString m_strIngredient;//配料
QString m_strBakingDegree;//烘培程度
};
#endif // PIZZA_H
pizza.cpp
cpp
#include "pizza.h"
#include <QDebug>
Pizza::Pizza() {}
void Pizza::setSauce(const QString strSauce)
{
m_strSauce = strSauce;
}
void Pizza::setCheese(const QString strCheese)
{
m_strCheese = strCheese;
}
void Pizza::setIngredient(const QString strIngredient)
{
m_strIngredient = strIngredient;
}
void Pizza::setBakingDegree(const QString strBakingDegree)
{
m_strBakingDegree = strBakingDegree;
}
void Pizza::displayPakageType() const
{
qDebug()<<"套餐类型:奶酪为"<<m_strSauce<<"酱料是"<<m_strCheese
<<"配料是"<<m_strIngredient<<"烘培程度"<<m_strBakingDegree;
}
builder.h
cpp
#ifndef BUILDER_H
#define BUILDER_H
class Builder{
public:
virtual void buildSauce() = 0;
virtual void buildCheese() = 0;
virtual void buildIngredient() = 0;
virtual void buildBakingDegree() = 0;
virtual ~Builder() = default;
};
#endif // BUILDER_H
builder1.h
cpp
#ifndef BUILDER1_H
#define BUILDER1_H
#include <Builder.h>
class Pizza;
class Builder1 : public Builder
{
public:
Builder1(Pizza* pizza);
void buildSauce()override;
void buildCheese()override;
void buildIngredient()override;
void buildBakingDegree()override;
Pizza* getPizza()const;
private:
Pizza* m_pizza;
};
#endif // BUILDER1_H
builder1.cpp
cpp
#include "builder1.h"
#include "pizza.h"
Builder1::Builder1(Pizza* pizza) {
m_pizza = pizza;
}
void Builder1::buildSauce()
{
m_pizza->setSauce("Thin and Crispy");
}
void Builder1::buildCheese()
{
m_pizza->setCheese("Tomatoes");
}
void Builder1::buildIngredient()
{
m_pizza->setIngredient("Mozzarella");
}
void Builder1::buildBakingDegree()
{
m_pizza->setBakingDegree("Sausage");
}
Pizza *Builder1::getPizza() const
{
return m_pizza;
}
builder2.h
cpp
#ifndef BUILDER2_H
#define BUILDER2_H
#include <Builder.h>
class Pizza;
class Builder2 : public Builder
{
public:
Builder2(Pizza* pizza);
void buildSauce()override;
void buildCheese()override;
void buildIngredient()override;
void buildBakingDegree()override;
Pizza* getPizza()const;
private:
Pizza* m_pizza;
};
#endif // BUILDER2_H
builder2.cpp
cpp
#include "builder2.h"
#include "pizza.h"
Builder2::Builder2(Pizza* pizza) {
m_pizza = pizza;
}
void Builder2::buildSauce()
{
m_pizza->setSauce("Thick Bottom");
}
void Builder2::buildCheese()
{
m_pizza->setCheese("Cream");
}
void Builder2::buildIngredient()
{
m_pizza->setIngredient("Cheddar");
}
void Builder2::buildBakingDegree()
{
m_pizza->setBakingDegree("Mushroom");
}
Pizza *Builder2::getPizza() const
{
return m_pizza;
}
commander.h
cpp
#ifndef COMMANDER_H
#define COMMANDER_H
class Builder;
class Commander
{
public:
void makePizza(Builder* builder);
};
#endif // COMMANDER_H
commander.cpp
cpp
#include "commander.h"
#include "Builder.h"
void Commander::makePizza(Builder *builder)
{
builder->buildSauce();
builder->buildCheese();
builder->buildIngredient();
builder->buildBakingDegree();
}
运行结果

程序设计模式是一个漫长的探索与理解的过程,其实好的程序员都是自己创建了设计模式而不自知,一般的也就只能去学去理解前人总结出来的。真正厉害的是那些发明了新东西的人,而普通人也只能在前人的基础上加以应用。