建造者模式核心思想,将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示
业务场景:复杂对象构建 —— Web服务器配置生成器
你需要创建一个 WebServerConfig 对象,它包含多个可选配置项:
- 监听端口
- 根目录
- 是否启用 HTTPS
- SSL 证书路径
- 日志级别
- 最大连接数
- Gzip 压缩
- 自定义中间件
这个对象字段多、部分可选、构造过程复杂,直接使用构造函数会导致:
- 参数爆炸(telescoping constructor)
- 难以阅读和维护
- 无法灵活组合
各类零散配置
#include <iostream>
#include <string>
#include <memory>
#include <vector>
using std::string;
using std::unique_ptr;
using std::vector;
// ==================== 日志级别枚举 ====================
enum class LogLevel {
DEBUG,
INFO,
WARN,
ERROR
};
string logLevelToString(LogLevel level) {
switch (level) {
case LogLevel::DEBUG: return "DEBUG";
case LogLevel::INFO: return "INFO";
case LogLevel::WARN: return "WARN";
case LogLevel::ERROR: return "ERROR";
default: return "UNKNOWN";
}
}
// ==================== 中间件类(可插拔组件)====================
class Middleware {
protected:
string name;
public:
Middleware(const string& n) : name(n) {}
virtual ~Middleware() = default;
virtual void handle() const = 0;
string getName() const { return name; }
};
class AuthMiddleware : public Middleware {
public:
AuthMiddleware() : Middleware("认证中间件") {}
void handle() const override {
std::cout << "🔐 执行身份验证\n";
}
};
class LoggingMiddleware : public Middleware {
public:
LoggingMiddleware() : Middleware("日志中间件") {}
void handle() const override {
std::cout << "📝 记录访问日志\n";
}
};
组合成最终配置类
// ==================== 最终产品:Web服务器配置 ====================
class WebServerConfig {
private:
int port;
string rootDir;
bool enableHttps;
string certFile;
string keyFile;
LogLevel logLevel;
int maxConnections;
bool enableGzip;
vector<unique_ptr<Middleware>> middlewares;
// 私有构造,只能由 Builder 创建
WebServerConfig() = default;
friend class WebServerConfigBuilder; // 允许 Builder 访问私有成员
public:
// 禁止拷贝,允许移动
WebServerConfig(const WebServerConfig&) = delete;
WebServerConfig& operator=(const WebServerConfig&) = delete;
WebServerConfig(WebServerConfig&&) = default;
WebServerConfig& operator=(WebServerConfig&&) = default;
~WebServerConfig() = default;
// 打印配置(用于调试)
void print() const {
std::cout << "\n🚀 Web服务器配置:\n";
std::cout << " 端口: " << port << "\n";
std::cout << " 根目录: " << rootDir << "\n";
std::cout << " HTTPS: " << (enableHttps ? "启用" : "禁用") << "\n";
if (enableHttps) {
std::cout << " 证书: " << certFile << "\n";
std::cout << " 私钥: " << keyFile << "\n";
}
std::cout << " 日志级别: " << logLevelToString(logLevel) << "\n";
std::cout << " 最大连接数: " << maxConnections << "\n";
std::cout << " Gzip压缩: " << (enableGzip ? "启用" : "禁用") << "\n";
std::cout << " 中间件: ";
if (middlewares.empty()) {
std::cout << "无\n";
} else {
for (size_t i = 0; i < middlewares.size(); ++i) {
std::cout << middlewares[i]->getName();
if (i < middlewares.size() - 1) std::cout << ", ";
}
std::cout << "\n";
}
std::cout << "\n";
}
// 提供只读访问(可选)
int getPort() const { return port; }
const string& getRootDir() const { return rootDir; }
bool isHttpsEnabled() const { return enableHttps; }
};
建造者类:WebServerConfigBuilder
class WebServerConfigBuilder {
private:
unique_ptr<WebServerConfig> config;
public:
WebServerConfigBuilder() {
config = std::make_unique<WebServerConfig>();
// 设置默认值
config->port = 8080;
config->rootDir = "./public";
config->enableHttps = false;
config->logLevel = LogLevel::INFO;
config->maxConnections = 1000;
config->enableGzip = false;
}
// 链式调用:设置端口
WebServerConfigBuilder& setPort(int p) {
if (p <= 0 || p > 65535) {
throw std::invalid_argument("端口必须在 1-65535 之间");
}
config->port = p;
return *this;
}
// 设置根目录
WebServerConfigBuilder& setRootDir(const string& dir) {
config->rootDir = dir;
return *this;
}
// 启用 HTTPS
WebServerConfigBuilder& enableHTTPS(const string& cert, const string& key) {
config->enableHttps = true;
config->certFile = cert;
config->keyFile = key;
return *this;
}
// 设置日志级别
WebServerConfigBuilder& setLogLevel(LogLevel level) {
config->logLevel = level;
return *this;
}
// 设置最大连接数
WebServerConfigBuilder& setMaxConnections(int maxConn) {
if (maxConn <= 0) {
throw std::invalid_argument("最大连接数必须大于0");
}
config->maxConnections = maxConn;
return *this;
}
// 启用 Gzip
WebServerConfigBuilder& enableGzip(bool on = true) {
config->enableGzip = on;
return *this;
}
// 添加中间件
WebServerConfigBuilder& addMiddleware(unique_ptr<Middleware> middleware) {
config->middlewares.push_back(std::move(middleware));
return *this;
}
// 构建最终对象(移动语义)
unique_ptr<WebServerConfig> build() {
// 可选:构建前验证
if (config->rootDir.empty()) {
throw std::runtime_error("根目录不能为空");
}
return std::move(config); // 转移所有权
}
};
创建不同配置的服务器
int main() {
std::cout << "欢迎使用 Web 服务器配置生成器\n\n";
// 场景1:开发环境配置
auto devConfig = WebServerConfigBuilder{}
.setPort(3000)
.setRootDir("./dev-public")
.setLogLevel(LogLevel::DEBUG)
.enableGzip()
.addMiddleware(std::make_unique<LoggingMiddleware>())
.build();
devConfig->print();
// 场景2:生产环境配置(HTTPS + 认证)
auto prodConfig = WebServerConfigBuilder{}
.setPort(443)
.setRootDir("/var/www/html")
.enableHTTPS("/certs/server.crt", "/certs/server.key")
.setMaxConnections(5000)
.enableGzip()
.addMiddleware(std::make_unique<AuthMiddleware>())
.addMiddleware(std::make_unique<LoggingMiddleware>())
.build();
prodConfig->print();
// 场景3:最小化配置(嵌入式设备)
auto tinyConfig = WebServerConfigBuilder{}
.setPort(80)
.setRootDir("./web")
.setLogLevel(LogLevel::ERROR)
.setMaxConnections(50)
.build();
tinyConfig->print();
return 0;
}
使用模板优化
#include <iostream>
#include <string>
#include <memory>
#include <vector>
using std::string;
using std::unique_ptr;
using std::vector;
// ================ 1. 中间件基类(用于扩展功能) ====================
// 所有中间件都继承自这个类
struct Middleware {
virtual ~Middleware() = default;
virtual void handle() const = 0;
virtual std::string getName() const = 0;
};
// 认证中间件示例
struct AuthMiddleware : Middleware {
void handle() const override { std::cout << "执行身份验证\n"; }
std::string getName() const override { return "认证中间件"; }
};
// 日志中间件示例
struct LoggingMiddleware : Middleware {
void handle() const override { std::cout << "记录访问日志\n"; }
std::string getName() const override { return "日志中间件"; }
};
// ============= 2. 策略配置类(每个配置项一个策略) ================
// 端口配置策略
struct PortPolicy {
int port = 8080; // 默认端口
// 设置端口并返回建造者自身(用于链式调用)
template<typename Builder>
Builder& setPort(Builder& builder, int p) {
builder.port = p;
return builder;
}
};
// 根目录策略
struct RootDirPolicy {
string rootDir = "./public"; // 默认路径
template<typename Builder>
Builder& setRootDir(Builder& builder, const string& dir) {
builder.rootDir = dir;
return builder;
}
};
// HTTPS 策略
struct HttpsPolicy {
bool enableHttps = false;
string certFile;
string keyFile;
// 模板builder类
template<typename Builder>
Builder& enableHTTPS(Builder& builder, const string& cert, const string& key) {
builder.enableHttps = true;
builder.certFile = cert;
builder.keyFile = key;
return builder;
}
};
// 日志级别策略
struct LogPolicy {
enum class LogLevel { DEBUG, INFO, WARN, ERROR };
LogLevel logLevel = LogLevel::INFO;
// 模板builder类
template<typename Builder>
Builder& setLogLevel(Builder& builder, LogLevel level) {
builder.logLevel = level;
return builder;
}
};
// 最大连接数策略
struct ConnectionPolicy {
int maxConnections = 1000;
// 模板builder类
template<typename Builder>
Builder& setMaxConnections(Builder& builder, int maxConn) {
builder.maxConnections = maxConn;
return builder;
}
};
// Gzip 压缩策略
struct GzipPolicy {
bool enableGzip = false;
// 模板builder类
template<typename Builder>
Builder& enableGzip(Builder& builder, bool on = true) {
builder.enableGzip = on;
return builder;
}
};
// 中间件列表策略
struct MiddlewarePolicy {
vector<unique_ptr<Middleware>> middlewares;
template<typename T>
struct is_middleware : std::is_base_of<Middleware, T> {};
template<typename Builder, typename T>
std::enable_if_t<is_middleware<T>::value, Builder&>
addMiddleware(Builder& builder) {
builder.middlewares.push_back(std::make_unique<T>());
return builder;
}
};
模板建造者类
// ==================== 3. 模板建造者(核心) ====================
// 使用模板参数接收多个策略,组合成最终的建造者
template<typename... Policies>
class WebServerBuilder : public Policies... {
public:
// 构造函数
WebServerBuilder() = default;
// 继承所有策略中的方法(C++17 支持 using...)
using Policies::setPort...;
using Policies::setRootDir...;
using Policies::enableHTTPS...;
using Policies::setLogLevel...;
using Policies::setMaxConnections...;
using Policies::enableGzip...;
using Policies::addMiddleware...;
// 最终配置结构体
struct Config {
int port;
string rootDir;
bool enableHttps;
string certFile, keyFile;
LogPolicy::LogLevel logLevel;
int maxConnections;
bool enableGzip;
vector<unique_ptr<Middleware>> middlewares;
// 打印配置信息
void print() const {
std::cout << "\n🚀 Web服务器配置:\n";
std::cout << " 端口: " << port << "\n";
std::cout << " 根目录: " << rootDir << "\n";
std::cout << " HTTPS: " << (enableHttps ? "启用" : "禁用") << "\n";
if (enableHttps) {
std::cout << " 证书: " << certFile << "\n";
std::cout << " 私钥: " << keyFile << "\n";
}
std::cout << " 日志级别: ";
switch (logLevel) {
case LogPolicy::LogLevel::DEBUG: std::cout << "DEBUG"; break;
case LogPolicy::LogLevel::INFO: std::cout << "INFO"; break;
case LogPolicy::LogLevel::WARN: std::cout << "WARN"; break;
case LogPolicy::LogLevel::ERROR: std::cout << "ERROR"; break;
}
std::cout << "\n";
std::cout << " 最大连接数: " << maxConnections << "\n";
std::cout << " Gzip压缩: " << (enableGzip ? "启用" : "禁用") << "\n";
std::cout << " 中间件: ";
if (middlewares.empty()) {
std::cout << "无\n";
} else {
for (size_t i = 0; i < middlewares.size(); ++i) {
std::cout << middlewares[i]->getName();
if (i < middlewares.size() - 1) std::cout << ", ";
}
std::cout << "\n";
}
std::cout << "\n";
}
};
// 构建最终的配置对象
unique_ptr<Config> build() {
auto config = std::make_unique<Config>();
config->port = port;
config->rootDir = rootDir;
config->enableHttps = enableHttps;
config->certFile = certFile;
config->keyFile = keyFile;
config->logLevel = logLevel;
config->maxConnections = maxConnections;
config->enableGzip = enableGzip;
config->middlewares = std::move(middlewares); // 转移所有权
return config;
}
};
// ============ 4. 定义不同类型的建造者(类型别名) ================
// 开发环境:不需要 HTTPS,但需要日志和 Gzip
using DevBuilder = WebServerBuilder<
PortPolicy,
RootDirPolicy,
LogPolicy,
GzipPolicy,
MiddlewarePolicy
>;
// 生产环境:需要 HTTPS、连接数限制等
using ProdBuilder = WebServerBuilder<
PortPolicy,
RootDirPolicy,
HttpsPolicy,
LogPolicy,
ConnectionPolicy,
GzipPolicy,
MiddlewarePolicy
>;
// ==================== 5. 使用示例 ====================
int main() {
std::cout << "欢迎使用简化版 C++17 建造者模式\n\n";
// 创建开发环境配置
auto devConfig = DevBuilder{}
.setPort(3000)
.setRootDir("./dev-public")
.setLogLevel(LogPolicy::LogLevel::DEBUG)
.enableGzip()
.addMiddleware<LoggingMiddleware>()
.build(); // 构建最终对象
devConfig->print();
// 创建生产环境配置
auto prodConfig = ProdBuilder{}
.setPort(443)
.setRootDir("/var/www/html")
.enableHTTPS("/certs/prod.crt", "/certs/prod.key")
.setMaxConnections(5000)
.setLogLevel(LogPolicy::LogLevel::INFO)
.enableGzip()
.addMiddleware<AuthMiddleware>()
.addMiddleware<LoggingMiddleware>()
.build();
prodConfig->print();
return 0;
}