建造者模式(Builder Pattern)是一种创建型设计模式,它将一个复杂对象的构建与它的表示分离,通过分步构建的方式创建对象,使得同样的构建过程可以创建不同的表示。
建造者模式有四个主要角色,分别是产品(Product)、抽象建造者(Builder)、具体建造者(Concrete Builder)和指挥者(Director)。
- 产品:需要创建的复杂对象。
- 抽象建造者:定义构建产品的抽象步骤。
- 具体建造者:实现抽象步骤,负责具体产品的部件创建和组装。
- 指挥者:控制构建流程的顺序,调用建造者的步骤完成对象创建。
- 目的:将复杂对象的创建过程封装起来,使得创建过程更加清晰、易于维护,同时也方便对创建过程进行扩展和修改。并且可以根据不同的具体建造者,创建出不同类型的产品。
- 创建复杂对象:当一个对象的创建过程比较复杂,需要多个步骤来完成,并且这些步骤的组合方式可能会发生变化时,适合使用建造者模式。
- 创建不同类型的对象:如果需要根据不同的需求创建不同类型的对象,且这些对象的创建过程有相似之处,可以使用建造者模式,通过不同的具体建造者来创建不同类型的对象。
C++订单系统demo:
数据库上层抽象:
class OrderDAO {
public:
// 根据订单ID查询订单类型
static string getOrderType(const string& orderId) {
// 实际实现:执行SQL查询订单类型
}
// 根据订单ID查询用户信息
static string getUserIdByOrderId(const string& orderId) {
// 实际实现:JOIN查询获取用户ID
}
// 根据订单ID查询商品信息
static vector<pair<string, double>> getProductsByOrderId(const string& orderId) {
// 实际实现:查询order_items表
}
// 根据订单ID查询优惠券信息
static pair<string, double> getCouponByOrderId(const string& orderId) {
// 实际实现:查询优惠券关联表
}
// 根据订单ID查询物流信息
static pair<string, string> getLogisticsByOrderId(const string& orderId) {
// 实际实现:查询物流表
};
业务处理逻辑:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
using namespace std;
// 辅助类:用户、商品、优惠券、物流信息
class User {
public:
string userId;
User(string id) : userId(id) {}
};
class Product {
public:
string productId;
double price;
Product(string id, double p) : productId(id), price(p) {}
};
class Coupon {
public:
string couponId;
double discount;
Coupon(string id, double d) : couponId(id), discount(d) {}
};
class Logistics {
public:
string logisticsId;
string company;
Logistics(string id, string c) : logisticsId(id), company(c) {}
};
// 产品类:订单(复杂对象)
class Order {
private:
string orderId; // 必选
string orderType; // 订单类型
User user; // 必选
vector<Product> items; // 必选
Coupon* coupon; // 可选
Logistics* logistics; // 可选
public:
// 构造函数:初始化必选参数和订单类型
Order(string oid, string type, User u, vector<Product> i)
: orderId(oid), orderType(type), user(u), items(i), coupon(nullptr), logistics(nullptr) {}
// 设置可选参数
void setCoupon(Coupon* c) { coupon = c; }
void setLogistics(Logistics* l) { logistics = l; }
// 展示订单信息
void show() {
cout << "订单ID: " << orderId << endl;
cout << "订单类型: " << (orderType == "NORMAL" ? "普通订单" : "预售订单") << endl;
cout << "用户ID: " << user.userId << endl;
cout << "商品列表: ";
for (auto& item : items) {
cout << item.productId << "(" << item.price << "元) ";
}
cout << endl;
if (coupon && !coupon->couponId.empty()) {
cout << "优惠券: " << coupon->couponId << "(" << coupon->discount << "折)" << endl;
} else {
cout << "未使用优惠券" << endl;
}
if (logistics && !logistics->logisticsId.empty()) {
cout << "物流信息: " << logistics->company << " " << logistics->logisticsId << endl;
} else {
cout << "未发货" << endl;
}
}
// 析构函数释放动态内存
~Order() {
delete coupon;
delete logistics;
}
};
// 抽象建造者:定义订单构建步骤,持有订单ID
class OrderBuilder {
protected:
Order* order; // 待构建的订单
string orderId; // 数据库主键:订单ID
public:
// 构造函数接收订单ID
OrderBuilder(string id) : orderId(id) {}
virtual ~OrderBuilder() { delete order; }
virtual void buildBasicInfo() = 0; // 构建必选基础信息
virtual void buildCoupon() = 0; // 构建优惠券
virtual void buildLogistics() = 0; // 构建物流
virtual Order* getResult() { return order; }
};
// 具体建造者1:普通订单建造者
class NormalOrderBuilder : public OrderBuilder {
public:
NormalOrderBuilder(string id) : OrderBuilder(id) {}
void buildBasicInfo() override {
// 从数据库查询基础信息
string userId = OrderDAO::getUserIdByOrderId(orderId);
User user(userId);
vector<pair<string, double>> productData = OrderDAO::getProductsByOrderId(orderId);
vector<Product> items;
for (auto& p : productData) {
items.emplace_back(p.first, p.second);
}
order = new Order(orderId, "NORMAL", user, items);
}
void buildCoupon() override {
// 从数据库查询优惠券
auto couponData = OrderDAO::getCouponByOrderId(orderId);
if (!couponData.first.empty()) {
order->setCoupon(new Coupon(couponData.first, couponData.second));
}
}
void buildLogistics() override {
// 从数据库查询物流信息
auto logisticsData = OrderDAO::getLogisticsByOrderId(orderId);
if (!logisticsData.first.empty()) {
order->setLogistics(new Logistics(logisticsData.first, logisticsData.second));
}
}
};
// 具体建造者2:预售订单建造者
class PresaleOrderBuilder : public OrderBuilder {
public:
PresaleOrderBuilder(string id) : OrderBuilder(id) {}
void buildBasicInfo() override {
// 从数据库查询基础信息
string userId = OrderDAO::getUserIdByOrderId(orderId);
User user(userId);
vector<pair<string, double>> productData = OrderDAO::getProductsByOrderId(orderId);
vector<Product> items;
for (auto& p : productData) {
items.emplace_back(p.first, p.second);
}
order = new Order(orderId, "PRESALE", user, items);
cout << "[预售订单] 已锁定库存" << endl;
}
void buildCoupon() override {
// 从数据库查询预售专属优惠券
auto couponData = OrderDAO::getCouponByOrderId(orderId);
order->setCoupon(new Coupon(couponData.first, couponData.second));
}
void buildLogistics() override {
// 从数据库查询物流信息(预售订单通常未发货)
auto logisticsData = OrderDAO::getLogisticsByOrderId(orderId);
if (!logisticsData.first.empty()) {
order->setLogistics(new Logistics(logisticsData.first, logisticsData.second));
} else {
cout << "[预售订单] 待发货(预计7天后发货)" << endl;
}
}
};
// 建造者工厂:根据订单ID创建对应类型的建造者
class OrderBuilderFactory {
public:
static OrderBuilder* createBuilder(const string& orderId) {
// 先查询订单类型
string orderType = OrderDAO::getOrderType(orderId);
// 根据类型创建对应建造者
if (orderType == "NORMAL") {
return new NormalOrderBuilder(orderId);
} else if (orderType == "PRESALE") {
return new PresaleOrderBuilder(orderId);
} else {
throw invalid_argument("未知订单类型");
}
}
};
// 指挥者:控制订单构建流程
class OrderDirector {
public:
Order* construct(OrderBuilder* builder) {
builder->buildBasicInfo(); // 第一步:构建必选信息
builder->buildCoupon(); // 第二步:处理优惠券
builder->buildLogistics(); // 第三步:处理物流
return builder->getResult();
}
};
// 客户端使用
int main() {
srand(time(0));
OrderDirector director;
// 1. 查询普通订单(已知订单ID)
cout << "=== 查询普通订单 ===" << endl;
string normalOrderId = "NORMAL_10086";
OrderBuilder* normalBuilder = OrderBuilderFactory::createBuilder(normalOrderId);
Order* normalOrder = director.construct(normalBuilder);
normalOrder->show();
// 2. 查询预售订单(已知订单ID)
cout << "\n=== 查询预售订单 ===" << endl;
string presaleOrderId = "PRESALE_10010";
OrderBuilder* presaleBuilder = OrderBuilderFactory::createBuilder(presaleOrderId);
Order* presaleOrder = director.construct(presaleBuilder);
presaleOrder->show();
return 0;
}
- 产品:包含必选属性(订单 ID、用户、商品列表)和可选属性(优惠券、物流),是最终要创建的复杂对象。
- 抽象建造者:定义订单构建的统一步骤(
buildBasicInfo
→buildCoupon
→buildLogistics
),并持有订单 ID 作为查询依据。 - 具体建造者:
- NormalOrderBuilder:实现普通订单的数据库驱动构建逻辑,从
OrderDAO
获取用户、商品,随机应用优惠券,自动关联物流信息。 - PresaleOrderBuilder:实现预售订单的特殊逻辑,从
OrderDAO
获取专属数据,包含库存锁定、强制使用预售优惠券、延迟发货提示等特有操作。
- NormalOrderBuilder:实现普通订单的数据库驱动构建逻辑,从
建造者工厂:根据订单 ID 自动判断订单类型并创建对应建造者:通过
OrderDAO.getOrderType
查询类型,屏蔽客户端对订单类型的判断逻辑,简化调用流程。- 指挥者:控制建造流程的执行顺序,确保必选信息先于可选信息构建:隔离客户端与具体构建细节,无论哪种订单类型,均按固定步骤完成构建。
运行效果示例
=== 查询普通订单 ===
订单ID: NORMAL_10086
订单类型: 普通订单
用户ID: user_001
商品列表: prod_001(99.9元) prod_002(199.9元)
优惠券: coupon_001(9折)
物流信息: 顺丰快递 logi_001
=== 查询预售订单 ===
[预售订单] 已锁定库存
[预售订单] 待发货(预计7天后发货)
订单ID: PRESALE_10010
订单类型: 预售订单
用户ID: user_002
商品列表: prod_003(2999元)
优惠券: presale_coupon_001(8.5折)
未发货
建造者模式的优势体现:
- 解决参数爆炸:无需通过构造函数传递大量参数,建造者通过数据库查询自动填充信息。
- 确保对象完整:指挥者强制必选信息优先构建,避免无效订单。
- 隔离变化点:普通 / 预售订单的差异逻辑封装在各自建造者中,修改时互不干扰。
- 支持灵活扩展:新增订单类型(如团购订单)时,只需新增
GroupBuyOrderBuilder
和工厂判断逻辑,完全符合开闭原则。
🦜🦜🦜.