# Client-Native 架构设计文档 ## 🏗️ 类图 (Class Diagram) ``` ┌─────────────────────────────┐ │ <> │ │ CertificateConfig │ ├─────────────────────────────┤ │ + GetClientCertificate() │ │ + GetClientPrivateKey() │ │ + GetCACertificate() │ │ + GetKeyPassword() │ └─────────────────────────────┘ △ │ uses │ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ CertificateManager │ │ SSLClientConnection │ ├─────────────────────────────┤ ├─────────────────────────────┤ │ - (no state) │ │ - m_sslContext: SSL_CTX* │ ├─────────────────────────────┤ │ - m_ssl: SSL* │ │ + LoadCertificateFromMemory()│◄───────┤ - m_socket: SOCKET │ │ + LoadPrivateKeyFromMemory()│ uses │ - m_isConnected: bool │ │ + PrintSSLError() │ │ - m_certManager: CertMgr │ └─────────────────────────────┘ ├─────────────────────────────┤ △ │ + Initialize() │ │ uses │ + Connect() │ │ │ + Send() │ │ │ + Receive() │ │ │ + Disconnect() │ ┌─────────────────────────────┐ │ + IsConnected() │ │ main() │ │ + GetCipherSuite() │ │ │ ├─────────────────────────────┤ │ [Application Entry Point] │───────>│ - InitializeWinsock() │ │ │ uses │ - Cleanup() │ └─────────────────────────────┘ └─────────────────────────────┘ ``` ## 📊 模块关系图 ``` main.cpp │ ├──► SSLClientConnection (主要依赖) │ │ │ ├──► CertificateManager (内部依赖) │ │ │ │ │ └──► OpenSSL API │ │ │ └──► Winsock2 API │ └──► CertificateConfig (直接依赖) ``` ## 🔄 对象生命周期 ``` ┌────── main() starts ──────┐ │ │ │ ┌──────────────────────┐ │ │ │ SSLClientConnection │ │ <── 创建对象(栈上) │ │ │ │ │ │ ┌────────────────┐ │ │ │ │ │ CertManager │ │ │ <── 自动创建成员对象 │ │ └────────────────┘ │ │ │ │ │ │ │ │ [Initialize] │ │ <── 分配SSL资源 │ │ └─> SSL_CTX* │ │ │ │ └─> 加载证书 │ │ │ │ │ │ │ │ [Connect] │ │ <── 分配Socket/SSL │ │ └─> SOCKET │ │ │ │ └─> SSL* │ │ │ │ └─> SSL握手 │ │ │ │ │ │ │ │ [Send/Receive] │ │ <── 数据传输 │ │ └─> SSL_write() │ │ │ │ └─> SSL_read() │ │ │ │ │ │ │ │ [~Destructor] │ │ <── 自动清理 │ │ └─> SSL_free() │ │ │ │ └─> closesocket()│ │ │ │ └─> SSL_CTX_free│ │ │ └──────────────────────┘ │ │ │ └────── main() ends ────────┘ (自动析构,无需手动清理) ``` ## 🎯 设计模式应用 ### 1. RAII (Resource Acquisition Is Initialization) ```cpp class SSLClientConnection { public: SSLClientConnection() // 构造函数 - 初始化状态 : m_sslContext(nullptr) , m_ssl(nullptr) , m_socket(INVALID_SOCKET) , m_isConnected(false) {} ~SSLClientConnection() // 析构函数 - 自动清理资源 { Cleanup(); // 释放SSL、Socket等资源 } // 禁止拷贝(避免资源重复释放) SSLClientConnection(const SSLClientConnection&) = delete; SSLClientConnection& operator=(const SSLClientConnection&) = delete; }; 使用: { SSLClientConnection client; // 自动调用构造函数 client.Initialize(...); client.Connect(...); // ... } // ← 离开作用域,自动调用析构函数清理 ``` ### 2. Static Factory (静态工厂) ```cpp class CertificateConfig { public: // 静态方法,无需实例化 static const char* GetClientCertificate() { return g_clientCert; } private: // 私有构造函数,防止实例化 CertificateConfig() = default; ~CertificateConfig() = default; }; 使用: const char* cert = CertificateConfig::GetClientCertificate(); // 直接调用 ``` ### 3. Manager Pattern (管理器模式) ```cpp class CertificateManager { public: // 无状态的工具方法 X509* LoadCertificateFromMemory(const char* certPem); EVP_PKEY* LoadPrivateKeyFromMemory(const char* keyPem, ...); static void PrintSSLError(const char* message); }; 使用: CertificateManager mgr; X509* cert = mgr.LoadCertificateFromMemory(certData); ``` ### 4. Facade Pattern (外观模式) ```cpp // SSLClientConnection 提供简化的接口 // 隐藏底层 OpenSSL + Winsock 的复杂性 class SSLClientConnection { public: // 简单易用的接口 bool Initialize(...); // 内部处理 SSL_CTX、证书加载等 bool Connect(...); // 内部处理 socket、SSL握手等 bool Send(...); // 内部处理 SSL_write int Receive(...); // 内部处理 SSL_read private: // 隐藏复杂的内部实现 bool InitializeWinsock(); void Cleanup(); // ... }; ``` ## 📐 架构层次 ``` ┌─────────────────────────────────────────┐ │ 应用层 (Application Layer) │ ← main.cpp │ - 用户交互 │ │ - 命令处理 │ │ - 主循环控制 │ └─────────────────────────────────────────┘ ↓ uses ┌─────────────────────────────────────────┐ │ 业务层 (Business Layer) │ ← SSLClientConnection │ - SSL连接管理 │ │ - 数据发送/接收 │ │ - 连接状态管理 │ └─────────────────────────────────────────┘ ↓ uses ┌─────────────────────────────────────────┐ │ 工具层 (Utility Layer) │ ← CertificateManager │ - 证书加载 │ │ - 错误处理 │ │ - 通用工具 │ └─────────────────────────────────────────┘ ↓ uses ┌─────────────────────────────────────────┐ │ 数据层 (Data Layer) │ ← CertificateConfig │ - 证书数据 │ │ - 配置数据 │ └─────────────────────────────────────────┘ ↓ uses ┌─────────────────────────────────────────┐ │ 系统层 (System Layer) │ │ - OpenSSL API │ │ - Winsock2 API │ │ - Windows API │ └─────────────────────────────────────────┘ ``` ## 🔐 数据流图 ### 初始化流程 ``` main() │ ├─> CertificateConfig::GetClientCertificate() │ │ │ └─> return g_clientCert │ ├─> SSLClientConnection::Initialize(cert, key, ca, pwd) │ │ │ ├─> SSL_CTX_new(TLS_client_method()) │ │ │ ├─> CertificateManager::LoadCertificateFromMemory(ca) │ │ │ │ │ ├─> BIO_new_mem_buf() │ │ ├─> PEM_read_bio_X509() │ │ └─> return X509* │ │ │ ├─> SSL_CTX_use_certificate() │ │ │ └─> SSL_CTX_use_PrivateKey() │ └─> SSLClientConnection::Connect(address, port) │ ├─> socket() → SOCKET ├─> connect() → TCP连接 ├─> SSL_new() → SSL* ├─> SSL_set_fd() └─> SSL_connect() → SSL握手 ``` ### 数据传输流程 ``` main() [用户输入 "1"] │ ├─> SSLClientConnection::Send("hello") │ │ │ └─> SSL_write(m_ssl, "hello", 5) │ │ │ └─> [加密] → 网络发送 │ └─> SSLClientConnection::Receive(buffer, size) │ └─> SSL_read(m_ssl, buffer, size) │ └─> 网络接收 → [解密] → buffer ``` ## 💾 内存布局 ``` Stack (栈): ┌──────────────────────────────────────┐ │ main() 函数帧 │ │ ├─ SSLClientConnection client; │ <── 完整对象 │ │ ├─ m_sslContext: SSL_CTX* │ <── 指针(8字节) │ │ ├─ m_ssl: SSL* │ <── 指针(8字节) │ │ ├─ m_socket: SOCKET │ <── 句柄(8字节) │ │ ├─ m_isConnected: bool │ <── 布尔(1字节) │ │ └─ m_certManager: CertMgr │ <── 空对象(1字节) │ │ │ │ └─ char receiveBuffer[1024]; │ <── 缓冲区 └──────────────────────────────────────┘ Heap (堆): ┌──────────────────────────────────────┐ │ SSL_CTX 结构体 ←─ m_sslContext │ │ SSL 结构体 ←─ m_ssl │ │ X509 证书对象 │ │ EVP_PKEY 私钥对象 │ │ ... │ └──────────────────────────────────────┘ 析构时自动释放所有堆内存 ``` ## 📊 编译依赖关系 ``` main.cpp ├─ #include "pch.h" ├─ #include "CertificateConfig.h" └─ #include "SSLClientConnection.h" SSLClientConnection.cpp ├─ #include "pch.h" ├─ #include "SSLClientConnection.h" └─ #include "CertificateManager.h" CertificateManager.cpp ├─ #include "pch.h" └─ #include "CertificateManager.h" CertificateConfig.cpp ├─ #include "pch.h" └─ #include "CertificateConfig.h" pch.h (预编译头) ├─ #include ├─ #include ├─ #include ├─ #include └─ ... (其他系统头文件) ``` ## 🧪 单元测试架构(未来扩展) ```cpp // 伪代码示例 TEST_SUITE(CertificateConfigTest) { TEST(GetClientCertificate_ReturnsValidCert) { const char* cert = CertificateConfig::GetClientCertificate(); ASSERT_NOT_NULL(cert); ASSERT_TRUE(strstr(cert, "BEGIN CERTIFICATE")); } } TEST_SUITE(CertificateManagerTest) { TEST(LoadCertificateFromMemory_ValidCert_ReturnsX509) { CertificateManager mgr; X509* cert = mgr.LoadCertificateFromMemory(validCert); ASSERT_NOT_NULL(cert); X509_free(cert); } TEST(LoadCertificateFromMemory_InvalidCert_ReturnsNull) { CertificateManager mgr; X509* cert = mgr.LoadCertificateFromMemory("invalid"); ASSERT_NULL(cert); } } TEST_SUITE(SSLClientConnectionTest) { TEST(Initialize_ValidCerts_ReturnsTrue) { SSLClientConnection client; bool result = client.Initialize( validCert, validKey, validCA, "password" ); ASSERT_TRUE(result); } TEST(Connect_InvalidAddress_ReturnsFalse) { SSLClientConnection client; client.Initialize(...); bool result = client.Connect("0.0.0.0", 99999); ASSERT_FALSE(result); } TEST(Send_NotConnected_ReturnsFalse) { SSLClientConnection client; bool result = client.Send("hello"); ASSERT_FALSE(result); } } ``` ## 🔧 配置和扩展点 ### 扩展点 1: 支持配置文件 ```cpp // 未来可以添加 class ConfigReader { public: ServerConfig ReadFromFile(const std::string& path); }; // 使用 ConfigReader reader; ServerConfig config = reader.ReadFromFile("config.json"); client.Connect(config.address, config.port); ``` ### 扩展点 2: 日志系统 ```cpp // 未来可以添加 class Logger { public: static void Info(const std::string& msg); static void Error(const std::string& msg); static void Debug(const std::string& msg); }; // 在SSLClientConnection中使用 Logger::Info("SSL握手成功"); Logger::Error("连接失败"); ``` ### 扩展点 3: 异步IO ```cpp // 未来可以添加 class AsyncSSLClient : public SSLClientConnection { public: std::future ConnectAsync(const char* addr, int port); std::future SendAsync(const std::string& data); std::future ReceiveAsync(char* buffer, int size); }; ``` ## 📈 性能考虑 | 方面 | 原版 | 重构版 | 说明 | |------|------|--------|------| | **函数调用开销** | 直接调用 | 通过对象调用 | 编译器内联优化,无差异 | | **内存使用** | 全局变量 | 栈上对象 | 相同(对象很小) | | **缓存友好性** | 中等 | 好 | 相关数据集中在对象内 | | **编译优化** | 好 | 好 | 现代编译器优化效果相同 | **结论**: 重构对运行时性能几乎无影响。 ## 📚 代码度量 ``` 复杂度 (Cyclomatic Complexity): - 原版 main(): ~25 (高复杂度) - 重构版 main(): ~8 (低复杂度) - SSLClientConnection::Connect(): ~12 (中等复杂度) - CertificateManager::Load*(): ~5 (低复杂度) 耦合度 (Coupling): - 原版: 高耦合(全局变量) - 重构版: 低耦合(依赖注入) 内聚度 (Cohesion): - 原版: 低内聚(功能分散) - 重构版: 高内聚(功能集中) ``` ## 🎓 学习建议 ### 初学者 1. 先理解原版 `main.cpp.backup` 2. 运行并测试原版代码 3. 阅读重构版各模块 4. 对比理解设计改进 ### 中级开发者 1. 分析类的职责划分 2. 理解RAII资源管理 3. 学习设计模式应用 4. 尝试添加单元测试 ### 高级开发者 1. 评估架构设计 2. 考虑性能优化 3. 扩展功能(如异步IO) 4. 改进错误处理 --- **总结**: 这个重构展示了从"过程式编程"到"面向对象编程"的完整转变,是学习现代C++工程实践的绝佳案例。