C++设计模式:建造者模式
建造者模式(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; // 数据库主键:订单IDpublic:// 构造函数接收订单IDOrderBuilder(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
和工厂判断逻辑,完全符合开闭原则。
🦜🦜🦜.