建造者模式
建造者设计模式
- 建造者设计模式的思想
- 应用场景
- 实现示例
- 项目结构
- 项目代码
- 运行结果
建造者设计模式属于创建型设计模式中的一个。
本文主要记录一下建造者设计模式的简单使用。
建造者设计模式的思想
首先建造者设计模式分为产品,建造者,指挥者三部分。
其中产品是最终呈现的东西;
建造者负责创建这个产品;
指挥者负责调用建造者来创建产品;
实现的过程中,需要考虑产品由哪几部分组成。而建造者需要去创建组成产品的部分,指挥者指挥建造者来执行具体的建造过程。它将复杂对象的构建过程与其表示分离,使得同一个构建过程可以创建不同的表示。
应用场景
1. 需要创建具有多个属性的复杂对象
当对象的构造需要设置大量属性,且这些属性可能有不同的组合时,构建者模式可以简化对象的创建过程。通过链式调用,可以灵活地设置所需的属性,避免构造函数参数过多或重载过多的问题。
2. 对象构造过程需要分步完成
某些对象的构造过程可能需要分步骤进行,例如先初始化必要属性,再设置可选属性。构建者模式允许分步骤构造对象,确保每一步的合法性,最终生成完整的对象。
3. 需要创建不可变对象
构建者模式常用于创建不可变对象(Immutable Object)。通过构建者逐步设置属性,最终调用build()方法生成不可变对象,避免对象在构造过程中被修改。
4. 不同构造方式导致对象差异较大
当同一类的对象可能有多种不同的表示或构造方式时,构建者模式可以封装不同的构造逻辑。例如,一个Pizza对象可能有多种配料组合,构建者可以封装这些组合的构造过程。
5. 避免使用多个构造函数
当类的构造函数参数过多或参数组合复杂时,使用构建者模式可以避免编写多个构造函数或使用冗长的参数列表。构建者模式通过方法名明确参数含义,提高代码可读性。
6. 需要隔离复杂对象的构造与表示
构建者模式将对象的构造过程与对象本身分离,使得相同的构造过程可以创建不同的对象表示。例如,一个文档构建者可以生成HTML或PDF格式的文档,而构造过程保持一致。
实现示例
项目结构
项目代码
main.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
#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
#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
#ifndef BUILDER_H
#define BUILDER_Hclass 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
#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
#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
#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
#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
#ifndef COMMANDER_H
#define COMMANDER_Hclass Builder;
class Commander
{
public:void makePizza(Builder* builder);
};#endif // COMMANDER_H
commander.cpp
#include "commander.h"#include "Builder.h"void Commander::makePizza(Builder *builder)
{builder->buildSauce();builder->buildCheese();builder->buildIngredient();builder->buildBakingDegree();
}
运行结果
程序设计模式是一个漫长的探索与理解的过程,其实好的程序员都是自己创建了设计模式而不自知,一般的也就只能去学去理解前人总结出来的。真正厉害的是那些发明了新东西的人,而普通人也只能在前人的基础上加以应用。