本章目标
- 掌握建造者模式的设计思想和实现方式
- 学会使用建造者模式构建复杂对象
- 理解原型模式的克隆机制
- 掌握深拷贝和浅拷贝的区别
- 学会在实际项目中应用这两种模式
- 了解现代编程语言中的建造者模式变体
4.1 建造者模式(Builder Pattern)
4.1.1 模式定义
建造者模式将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
核心思想: - 分步骤构建复杂对象 - 隐藏对象构建的复杂性 - 支持不同的构建过程 - 提供流畅的API接口
适用场景: - 对象有很多可选参数 - 对象创建过程复杂 - 需要创建不同配置的同类对象 - 构造函数参数过多
4.1.2 传统建造者模式
// 产品类:计算机
class Computer {
// 必需参数
private final String cpu;
private final String memory;
// 可选参数
private final String storage;
private final String graphicsCard;
private final String motherboard;
private final String powerSupply;
private final String coolingSystem;
private final boolean hasWiFi;
private final boolean hasBluetooth;
private final String operatingSystem;
// 私有构造函数,只能通过Builder创建
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.memory = builder.memory;
this.storage = builder.storage;
this.graphicsCard = builder.graphicsCard;
this.motherboard = builder.motherboard;
this.powerSupply = builder.powerSupply;
this.coolingSystem = builder.coolingSystem;
this.hasWiFi = builder.hasWiFi;
this.hasBluetooth = builder.hasBluetooth;
this.operatingSystem = builder.operatingSystem;
}
// 静态内部Builder类
public static class Builder {
// 必需参数
private final String cpu;
private final String memory;
// 可选参数,设置默认值
private String storage = "256GB SSD";
private String graphicsCard = "Integrated";
private String motherboard = "Standard";
private String powerSupply = "500W";
private String coolingSystem = "Air Cooling";
private boolean hasWiFi = true;
private boolean hasBluetooth = true;
private String operatingSystem = "Windows 11";
// Builder构造函数,只接受必需参数
public Builder(String cpu, String memory) {
this.cpu = cpu;
this.memory = memory;
}
// 流畅接口方法
public Builder storage(String storage) {
this.storage = storage;
return this;
}
public Builder graphicsCard(String graphicsCard) {
this.graphicsCard = graphicsCard;
return this;
}
public Builder motherboard(String motherboard) {
this.motherboard = motherboard;
return this;
}
public Builder powerSupply(String powerSupply) {
this.powerSupply = powerSupply;
return this;
}
public Builder coolingSystem(String coolingSystem) {
this.coolingSystem = coolingSystem;
return this;
}
public Builder wifi(boolean hasWiFi) {
this.hasWiFi = hasWiFi;
return this;
}
public Builder bluetooth(boolean hasBluetooth) {
this.hasBluetooth = hasBluetooth;
return this;
}
public Builder operatingSystem(String operatingSystem) {
this.operatingSystem = operatingSystem;
return this;
}
// 构建方法
public Computer build() {
// 可以在这里添加验证逻辑
validateConfiguration();
return new Computer(this);
}
private void validateConfiguration() {
// 验证配置的合理性
if (cpu == null || cpu.trim().isEmpty()) {
throw new IllegalArgumentException("CPU cannot be null or empty");
}
if (memory == null || memory.trim().isEmpty()) {
throw new IllegalArgumentException("Memory cannot be null or empty");
}
// 检查高端显卡是否需要更强的电源
if (graphicsCard.contains("RTX 4090") && !powerSupply.contains("850W")) {
System.out.println("Warning: RTX 4090 may require at least 850W power supply");
}
// 检查CPU和内存的匹配
if (cpu.contains("i9") && !memory.contains("32GB")) {
System.out.println("Recommendation: i9 CPU works best with 32GB+ memory");
}
}
}
// Getter方法
public String getCpu() { return cpu; }
public String getMemory() { return memory; }
public String getStorage() { return storage; }
public String getGraphicsCard() { return graphicsCard; }
public String getMotherboard() { return motherboard; }
public String getPowerSupply() { return powerSupply; }
public String getCoolingSystem() { return coolingSystem; }
public boolean hasWiFi() { return hasWiFi; }
public boolean hasBluetooth() { return hasBluetooth; }
public String getOperatingSystem() { return operatingSystem; }
@Override
public String toString() {
return String.format(
"Computer Configuration:\n" +
" CPU: %s\n" +
" Memory: %s\n" +
" Storage: %s\n" +
" Graphics Card: %s\n" +
" Motherboard: %s\n" +
" Power Supply: %s\n" +
" Cooling System: %s\n" +
" WiFi: %s\n" +
" Bluetooth: %s\n" +
" Operating System: %s",
cpu, memory, storage, graphicsCard, motherboard,
powerSupply, coolingSystem, hasWiFi ? "Yes" : "No",
hasBluetooth ? "Yes" : "No", operatingSystem
);
}
}
// 使用示例
public class BuilderPatternDemo {
public static void main(String[] args) {
System.out.println("=== Builder Pattern Demo ===");
// 创建基础配置的计算机
Computer basicComputer = new Computer.Builder("Intel i5-12400", "16GB DDR4")
.build();
System.out.println("Basic Computer:");
System.out.println(basicComputer);
System.out.println();
// 创建游戏配置的计算机
Computer gamingComputer = new Computer.Builder("Intel i7-13700K", "32GB DDR5")
.storage("1TB NVMe SSD")
.graphicsCard("NVIDIA RTX 4070")
.motherboard("ASUS ROG Strix Z790")
.powerSupply("750W 80+ Gold")
.coolingSystem("Liquid Cooling")
.operatingSystem("Windows 11 Pro")
.build();
System.out.println("Gaming Computer:");
System.out.println(gamingComputer);
System.out.println();
// 创建工作站配置的计算机
Computer workstationComputer = new Computer.Builder("Intel i9-13900K", "64GB DDR5")
.storage("2TB NVMe SSD + 4TB HDD")
.graphicsCard("NVIDIA RTX 4090")
.motherboard("ASUS ProArt Z790")
.powerSupply("1000W 80+ Platinum")
.coolingSystem("Custom Loop Liquid Cooling")
.wifi(true)
.bluetooth(true)
.operatingSystem("Windows 11 Pro for Workstations")
.build();
System.out.println("Workstation Computer:");
System.out.println(workstationComputer);
System.out.println();
// 创建服务器配置的计算机
Computer serverComputer = new Computer.Builder("Intel Xeon W-3375", "128GB ECC DDR4")
.storage("4x 2TB NVMe SSD RAID 10")
.graphicsCard("None")
.motherboard("Supermicro X12SPW-TF")
.powerSupply("1600W Redundant")
.coolingSystem("Server Grade Air Cooling")
.wifi(false)
.bluetooth(false)
.operatingSystem("Windows Server 2022")
.build();
System.out.println("Server Computer:");
System.out.println(serverComputer);
}
}
4.1.3 Director模式变体
from abc import ABC, abstractmethod
from typing import List, Optional
from enum import Enum
class DatabaseType(Enum):
MYSQL = "MySQL"
POSTGRESQL = "PostgreSQL"
MONGODB = "MongoDB"
REDIS = "Redis"
class EnvironmentType(Enum):
DEVELOPMENT = "development"
TESTING = "testing"
STAGING = "staging"
PRODUCTION = "production"
# 产品类:数据库配置
class DatabaseConfig:
def __init__(self):
self.host: str = "localhost"
self.port: int = 3306
self.database: str = "myapp"
self.username: str = "root"
self.password: str = ""
self.db_type: DatabaseType = DatabaseType.MYSQL
self.environment: EnvironmentType = EnvironmentType.DEVELOPMENT
self.ssl_enabled: bool = False
self.connection_pool_size: int = 10
self.connection_timeout: int = 30
self.read_timeout: int = 60
self.charset: str = "utf8mb4"
self.timezone: str = "UTC"
self.backup_enabled: bool = False
self.backup_schedule: str = "0 2 * * *" # 每天凌晨2点
self.monitoring_enabled: bool = False
self.log_queries: bool = False
self.cache_enabled: bool = False
self.replication_enabled: bool = False
self.master_host: Optional[str] = None
self.slave_hosts: List[str] = []
def get_connection_string(self) -> str:
"""生成数据库连接字符串"""
if self.db_type == DatabaseType.MYSQL:
return f"mysql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
elif self.db_type == DatabaseType.POSTGRESQL:
return f"postgresql://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
elif self.db_type == DatabaseType.MONGODB:
return f"mongodb://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
elif self.db_type == DatabaseType.REDIS:
return f"redis://:{self.password}@{self.host}:{self.port}/0"
else:
return f"unknown://{self.host}:{self.port}/{self.database}"
def __str__(self) -> str:
config_lines = [
f"Database Configuration ({self.environment.value}):",
f" Type: {self.db_type.value}",
f" Host: {self.host}:{self.port}",
f" Database: {self.database}",
f" Username: {self.username}",
f" SSL: {'Enabled' if self.ssl_enabled else 'Disabled'}",
f" Connection Pool: {self.connection_pool_size}",
f" Timeouts: Connect={self.connection_timeout}s, Read={self.read_timeout}s",
f" Charset: {self.charset}",
f" Timezone: {self.timezone}",
f" Backup: {'Enabled' if self.backup_enabled else 'Disabled'}",
f" Monitoring: {'Enabled' if self.monitoring_enabled else 'Disabled'}",
f" Query Logging: {'Enabled' if self.log_queries else 'Disabled'}",
f" Cache: {'Enabled' if self.cache_enabled else 'Disabled'}",
f" Replication: {'Enabled' if self.replication_enabled else 'Disabled'}"
]
if self.replication_enabled:
config_lines.append(f" Master: {self.master_host}")
config_lines.append(f" Slaves: {', '.join(self.slave_hosts)}")
return "\n".join(config_lines)
# 抽象建造者
class DatabaseConfigBuilder(ABC):
def __init__(self):
self.config = DatabaseConfig()
@abstractmethod
def set_basic_connection(self) -> 'DatabaseConfigBuilder':
pass
@abstractmethod
def set_security_settings(self) -> 'DatabaseConfigBuilder':
pass
@abstractmethod
def set_performance_settings(self) -> 'DatabaseConfigBuilder':
pass
@abstractmethod
def set_backup_settings(self) -> 'DatabaseConfigBuilder':
pass
@abstractmethod
def set_monitoring_settings(self) -> 'DatabaseConfigBuilder':
pass
def get_result(self) -> DatabaseConfig:
return self.config
# 具体建造者:开发环境
class DevelopmentConfigBuilder(DatabaseConfigBuilder):
def set_basic_connection(self) -> 'DatabaseConfigBuilder':
self.config.host = "localhost"
self.config.port = 3306
self.config.database = "myapp_dev"
self.config.username = "dev_user"
self.config.password = "dev_password"
self.config.db_type = DatabaseType.MYSQL
self.config.environment = EnvironmentType.DEVELOPMENT
return self
def set_security_settings(self) -> 'DatabaseConfigBuilder':
self.config.ssl_enabled = False # 开发环境不需要SSL
return self
def set_performance_settings(self) -> 'DatabaseConfigBuilder':
self.config.connection_pool_size = 5
self.config.connection_timeout = 10
self.config.read_timeout = 30
self.config.cache_enabled = False
return self
def set_backup_settings(self) -> 'DatabaseConfigBuilder':
self.config.backup_enabled = False # 开发环境不需要备份
return self
def set_monitoring_settings(self) -> 'DatabaseConfigBuilder':
self.config.monitoring_enabled = False
self.config.log_queries = True # 开发环境记录查询日志
return self
# 具体建造者:生产环境
class ProductionConfigBuilder(DatabaseConfigBuilder):
def set_basic_connection(self) -> 'DatabaseConfigBuilder':
self.config.host = "prod-db.company.com"
self.config.port = 3306
self.config.database = "myapp_prod"
self.config.username = "prod_user"
self.config.password = "secure_prod_password_123!"
self.config.db_type = DatabaseType.MYSQL
self.config.environment = EnvironmentType.PRODUCTION
return self
def set_security_settings(self) -> 'DatabaseConfigBuilder':
self.config.ssl_enabled = True
return self
def set_performance_settings(self) -> 'DatabaseConfigBuilder':
self.config.connection_pool_size = 50
self.config.connection_timeout = 30
self.config.read_timeout = 60
self.config.cache_enabled = True
return self
def set_backup_settings(self) -> 'DatabaseConfigBuilder':
self.config.backup_enabled = True
self.config.backup_schedule = "0 2 * * *" # 每天凌晨2点备份
return self
def set_monitoring_settings(self) -> 'DatabaseConfigBuilder':
self.config.monitoring_enabled = True
self.config.log_queries = False # 生产环境不记录查询日志(性能考虑)
return self
# 具体建造者:高可用生产环境
class HighAvailabilityConfigBuilder(DatabaseConfigBuilder):
def set_basic_connection(self) -> 'DatabaseConfigBuilder':
self.config.host = "prod-db-master.company.com"
self.config.port = 3306
self.config.database = "myapp_prod"
self.config.username = "ha_user"
self.config.password = "ultra_secure_ha_password_456!"
self.config.db_type = DatabaseType.MYSQL
self.config.environment = EnvironmentType.PRODUCTION
return self
def set_security_settings(self) -> 'DatabaseConfigBuilder':
self.config.ssl_enabled = True
return self
def set_performance_settings(self) -> 'DatabaseConfigBuilder':
self.config.connection_pool_size = 100
self.config.connection_timeout = 30
self.config.read_timeout = 60
self.config.cache_enabled = True
return self
def set_backup_settings(self) -> 'DatabaseConfigBuilder':
self.config.backup_enabled = True
self.config.backup_schedule = "0 */6 * * *" # 每6小时备份一次
return self
def set_monitoring_settings(self) -> 'DatabaseConfigBuilder':
self.config.monitoring_enabled = True
self.config.log_queries = False
return self
def set_replication(self) -> 'DatabaseConfigBuilder':
self.config.replication_enabled = True
self.config.master_host = "prod-db-master.company.com"
self.config.slave_hosts = [
"prod-db-slave1.company.com",
"prod-db-slave2.company.com",
"prod-db-slave3.company.com"
]
return self
# Director类:指导构建过程
class DatabaseConfigDirector:
def __init__(self, builder: DatabaseConfigBuilder):
self.builder = builder
def construct_basic_config(self) -> DatabaseConfig:
"""构建基础配置"""
return (self.builder
.set_basic_connection()
.set_security_settings()
.get_result())
def construct_full_config(self) -> DatabaseConfig:
"""构建完整配置"""
return (self.builder
.set_basic_connection()
.set_security_settings()
.set_performance_settings()
.set_backup_settings()
.set_monitoring_settings()
.get_result())
def construct_ha_config(self) -> DatabaseConfig:
"""构建高可用配置"""
config = (self.builder
.set_basic_connection()
.set_security_settings()
.set_performance_settings()
.set_backup_settings()
.set_monitoring_settings()
.get_result())
# 如果是高可用建造者,设置复制
if isinstance(self.builder, HighAvailabilityConfigBuilder):
self.builder.set_replication()
return config
# 流畅接口建造者(现代风格)
class FluentDatabaseConfigBuilder:
def __init__(self):
self.config = DatabaseConfig()
def host(self, host: str) -> 'FluentDatabaseConfigBuilder':
self.config.host = host
return self
def port(self, port: int) -> 'FluentDatabaseConfigBuilder':
self.config.port = port
return self
def database(self, database: str) -> 'FluentDatabaseConfigBuilder':
self.config.database = database
return self
def credentials(self, username: str, password: str) -> 'FluentDatabaseConfigBuilder':
self.config.username = username
self.config.password = password
return self
def db_type(self, db_type: DatabaseType) -> 'FluentDatabaseConfigBuilder':
self.config.db_type = db_type
return self
def environment(self, env: EnvironmentType) -> 'FluentDatabaseConfigBuilder':
self.config.environment = env
return self
def ssl(self, enabled: bool = True) -> 'FluentDatabaseConfigBuilder':
self.config.ssl_enabled = enabled
return self
def connection_pool(self, size: int) -> 'FluentDatabaseConfigBuilder':
self.config.connection_pool_size = size
return self
def timeouts(self, connect: int, read: int) -> 'FluentDatabaseConfigBuilder':
self.config.connection_timeout = connect
self.config.read_timeout = read
return self
def charset(self, charset: str) -> 'FluentDatabaseConfigBuilder':
self.config.charset = charset
return self
def timezone(self, timezone: str) -> 'FluentDatabaseConfigBuilder':
self.config.timezone = timezone
return self
def backup(self, enabled: bool = True, schedule: str = "0 2 * * *") -> 'FluentDatabaseConfigBuilder':
self.config.backup_enabled = enabled
self.config.backup_schedule = schedule
return self
def monitoring(self, enabled: bool = True) -> 'FluentDatabaseConfigBuilder':
self.config.monitoring_enabled = enabled
return self
def query_logging(self, enabled: bool = True) -> 'FluentDatabaseConfigBuilder':
self.config.log_queries = enabled
return self
def cache(self, enabled: bool = True) -> 'FluentDatabaseConfigBuilder':
self.config.cache_enabled = enabled
return self
def replication(self, master: str, slaves: List[str]) -> 'FluentDatabaseConfigBuilder':
self.config.replication_enabled = True
self.config.master_host = master
self.config.slave_hosts = slaves
return self
def build(self) -> DatabaseConfig:
# 验证配置
self._validate()
return self.config
def _validate(self):
"""验证配置的有效性"""
if not self.config.host:
raise ValueError("Host cannot be empty")
if not self.config.database:
raise ValueError("Database name cannot be empty")
if not self.config.username:
raise ValueError("Username cannot be empty")
if self.config.port <= 0 or self.config.port > 65535:
raise ValueError("Port must be between 1 and 65535")
if self.config.connection_pool_size <= 0:
raise ValueError("Connection pool size must be positive")
# 使用示例
def test_builder_pattern():
print("=== Builder Pattern Demo ===")
# 使用传统Director模式
print("\n1. Traditional Director Pattern:")
print("-" * 40)
# 开发环境配置
dev_builder = DevelopmentConfigBuilder()
dev_director = DatabaseConfigDirector(dev_builder)
dev_config = dev_director.construct_full_config()
print("Development Configuration:")
print(dev_config)
print(f"Connection String: {dev_config.get_connection_string()}")
print()
# 生产环境配置
prod_builder = ProductionConfigBuilder()
prod_director = DatabaseConfigDirector(prod_builder)
prod_config = prod_director.construct_full_config()
print("Production Configuration:")
print(prod_config)
print(f"Connection String: {prod_config.get_connection_string()}")
print()
# 高可用生产环境配置
ha_builder = HighAvailabilityConfigBuilder()
ha_director = DatabaseConfigDirector(ha_builder)
ha_config = ha_director.construct_ha_config()
print("High Availability Configuration:")
print(ha_config)
print(f"Connection String: {ha_config.get_connection_string()}")
print()
# 使用流畅接口建造者
print("\n2. Fluent Interface Builder:")
print("-" * 40)
# 自定义配置
custom_config = (FluentDatabaseConfigBuilder()
.host("custom-db.example.com")
.port(5432)
.database("custom_app")
.credentials("custom_user", "custom_pass")
.db_type(DatabaseType.POSTGRESQL)
.environment(EnvironmentType.STAGING)
.ssl(True)
.connection_pool(25)
.timeouts(20, 45)
.charset("utf8")
.timezone("America/New_York")
.backup(True, "0 3 * * 0") # 每周日凌晨3点
.monitoring(True)
.query_logging(False)
.cache(True)
.build())
print("Custom Configuration:")
print(custom_config)
print(f"Connection String: {custom_config.get_connection_string()}")
print()
# MongoDB配置示例
mongo_config = (FluentDatabaseConfigBuilder()
.host("mongo-cluster.example.com")
.port(27017)
.database("analytics")
.credentials("mongo_user", "mongo_pass")
.db_type(DatabaseType.MONGODB)
.environment(EnvironmentType.PRODUCTION)
.ssl(True)
.connection_pool(30)
.timeouts(15, 30)
.monitoring(True)
.build())
print("MongoDB Configuration:")
print(mongo_config)
print(f"Connection String: {mongo_config.get_connection_string()}")
print()
# Redis配置示例
redis_config = (FluentDatabaseConfigBuilder()
.host("redis-cluster.example.com")
.port(6379)
.database("cache")
.credentials("", "redis_password")
.db_type(DatabaseType.REDIS)
.environment(EnvironmentType.PRODUCTION)
.ssl(True)
.connection_pool(20)
.timeouts(5, 10)
.monitoring(True)
.build())
print("Redis Configuration:")
print(redis_config)
print(f"Connection String: {redis_config.get_connection_string()}")
if __name__ == "__main__":
test_builder_pattern()
4.1.4 现代语言中的建造者模式
package main
import (
"fmt"
"strings"
"time"
)
// HTTPClient 配置结构
type HTTPClient struct {
baseURL string
timeout time.Duration
retryCount int
retryDelay time.Duration
userAgent string
headers map[string]string
cookies map[string]string
proxy string
tlsSkipVerify bool
followRedirect bool
maxRedirects int
compression bool
keepAlive bool
maxIdleConns int
logRequests bool
logResponses bool
}
// String 返回客户端配置的字符串表示
func (c *HTTPClient) String() string {
var parts []string
parts = append(parts, fmt.Sprintf("Base URL: %s", c.baseURL))
parts = append(parts, fmt.Sprintf("Timeout: %v", c.timeout))
parts = append(parts, fmt.Sprintf("Retry: %d times with %v delay", c.retryCount, c.retryDelay))
parts = append(parts, fmt.Sprintf("User Agent: %s", c.userAgent))
parts = append(parts, fmt.Sprintf("Headers: %d", len(c.headers)))
parts = append(parts, fmt.Sprintf("Cookies: %d", len(c.cookies)))
parts = append(parts, fmt.Sprintf("Proxy: %s", c.proxy))
parts = append(parts, fmt.Sprintf("TLS Skip Verify: %t", c.tlsSkipVerify))
parts = append(parts, fmt.Sprintf("Follow Redirect: %t", c.followRedirect))
parts = append(parts, fmt.Sprintf("Max Redirects: %d", c.maxRedirects))
parts = append(parts, fmt.Sprintf("Compression: %t", c.compression))
parts = append(parts, fmt.Sprintf("Keep Alive: %t", c.keepAlive))
parts = append(parts, fmt.Sprintf("Max Idle Connections: %d", c.maxIdleConns))
parts = append(parts, fmt.Sprintf("Log Requests: %t", c.logRequests))
parts = append(parts, fmt.Sprintf("Log Responses: %t", c.logResponses))
return strings.Join(parts, "\n")
}
// HTTPClientBuilder 建造者结构
type HTTPClientBuilder struct {
client *HTTPClient
}
// NewHTTPClientBuilder 创建新的建造者
func NewHTTPClientBuilder() *HTTPClientBuilder {
return &HTTPClientBuilder{
client: &HTTPClient{
baseURL: "http://localhost",
timeout: 30 * time.Second,
retryCount: 3,
retryDelay: 1 * time.Second,
userAgent: "Go-HTTP-Client/1.0",
headers: make(map[string]string),
cookies: make(map[string]string),
proxy: "",
tlsSkipVerify: false,
followRedirect: true,
maxRedirects: 10,
compression: true,
keepAlive: true,
maxIdleConns: 100,
logRequests: false,
logResponses: false,
},
}
}
// BaseURL 设置基础URL
func (b *HTTPClientBuilder) BaseURL(url string) *HTTPClientBuilder {
b.client.baseURL = url
return b
}
// Timeout 设置超时时间
func (b *HTTPClientBuilder) Timeout(timeout time.Duration) *HTTPClientBuilder {
b.client.timeout = timeout
return b
}
// Retry 设置重试配置
func (b *HTTPClientBuilder) Retry(count int, delay time.Duration) *HTTPClientBuilder {
b.client.retryCount = count
b.client.retryDelay = delay
return b
}
// UserAgent 设置用户代理
func (b *HTTPClientBuilder) UserAgent(userAgent string) *HTTPClientBuilder {
b.client.userAgent = userAgent
return b
}
// Header 添加请求头
func (b *HTTPClientBuilder) Header(key, value string) *HTTPClientBuilder {
b.client.headers[key] = value
return b
}
// Headers 批量设置请求头
func (b *HTTPClientBuilder) Headers(headers map[string]string) *HTTPClientBuilder {
for k, v := range headers {
b.client.headers[k] = v
}
return b
}
// Cookie 添加Cookie
func (b *HTTPClientBuilder) Cookie(key, value string) *HTTPClientBuilder {
b.client.cookies[key] = value
return b
}
// Cookies 批量设置Cookie
func (b *HTTPClientBuilder) Cookies(cookies map[string]string) *HTTPClientBuilder {
for k, v := range cookies {
b.client.cookies[k] = v
}
return b
}
// Proxy 设置代理
func (b *HTTPClientBuilder) Proxy(proxy string) *HTTPClientBuilder {
b.client.proxy = proxy
return b
}
// TLSSkipVerify 设置是否跳过TLS验证
func (b *HTTPClientBuilder) TLSSkipVerify(skip bool) *HTTPClientBuilder {
b.client.tlsSkipVerify = skip
return b
}
// FollowRedirect 设置是否跟随重定向
func (b *HTTPClientBuilder) FollowRedirect(follow bool) *HTTPClientBuilder {
b.client.followRedirect = follow
return b
}
// MaxRedirects 设置最大重定向次数
func (b *HTTPClientBuilder) MaxRedirects(max int) *HTTPClientBuilder {
b.client.maxRedirects = max
return b
}
// Compression 设置是否启用压缩
func (b *HTTPClientBuilder) Compression(enabled bool) *HTTPClientBuilder {
b.client.compression = enabled
return b
}
// KeepAlive 设置是否启用Keep-Alive
func (b *HTTPClientBuilder) KeepAlive(enabled bool) *HTTPClientBuilder {
b.client.keepAlive = enabled
return b
}
// MaxIdleConns 设置最大空闲连接数
func (b *HTTPClientBuilder) MaxIdleConns(max int) *HTTPClientBuilder {
b.client.maxIdleConns = max
return b
}
// LogRequests 设置是否记录请求日志
func (b *HTTPClientBuilder) LogRequests(enabled bool) *HTTPClientBuilder {
b.client.logRequests = enabled
return b
}
// LogResponses 设置是否记录响应日志
func (b *HTTPClientBuilder) LogResponses(enabled bool) *HTTPClientBuilder {
b.client.logResponses = enabled
return b
}
// Build 构建HTTPClient
func (b *HTTPClientBuilder) Build() (*HTTPClient, error) {
// 验证配置
if err := b.validate(); err != nil {
return nil, err
}
return b.client, nil
}
// validate 验证配置的有效性
func (b *HTTPClientBuilder) validate() error {
if b.client.baseURL == "" {
return fmt.Errorf("base URL cannot be empty")
}
if b.client.timeout <= 0 {
return fmt.Errorf("timeout must be positive")
}
if b.client.retryCount < 0 {
return fmt.Errorf("retry count cannot be negative")
}
if b.client.maxRedirects < 0 {
return fmt.Errorf("max redirects cannot be negative")
}
if b.client.maxIdleConns <= 0 {
return fmt.Errorf("max idle connections must be positive")
}
return nil
}
// 预定义的建造者配置
// ForDevelopment 创建开发环境配置
func ForDevelopment() *HTTPClientBuilder {
return NewHTTPClientBuilder().
Timeout(10 * time.Second).
Retry(1, 500*time.Millisecond).
TLSSkipVerify(true).
LogRequests(true).
LogResponses(true)
}
// ForProduction 创建生产环境配置
func ForProduction() *HTTPClientBuilder {
return NewHTTPClientBuilder().
Timeout(30 * time.Second).
Retry(3, 2*time.Second).
TLSSkipVerify(false).
Compression(true).
KeepAlive(true).
MaxIdleConns(100).
LogRequests(false).
LogResponses(false)
}
// ForTesting 创建测试环境配置
func ForTesting() *HTTPClientBuilder {
return NewHTTPClientBuilder().
Timeout(5 * time.Second).
Retry(0, 0).
FollowRedirect(false).
LogRequests(true).
LogResponses(true)
}
// 函数式选项模式(Go语言推荐的替代方案)
type ClientOption func(*HTTPClient)
// WithBaseURL 设置基础URL
func WithBaseURL(url string) ClientOption {
return func(c *HTTPClient) {
c.baseURL = url
}
}
// WithTimeout 设置超时时间
func WithTimeout(timeout time.Duration) ClientOption {
return func(c *HTTPClient) {
c.timeout = timeout
}
}
// WithRetry 设置重试配置
func WithRetry(count int, delay time.Duration) ClientOption {
return func(c *HTTPClient) {
c.retryCount = count
c.retryDelay = delay
}
}
// WithUserAgent 设置用户代理
func WithUserAgent(userAgent string) ClientOption {
return func(c *HTTPClient) {
c.userAgent = userAgent
}
}
// WithHeaders 设置请求头
func WithHeaders(headers map[string]string) ClientOption {
return func(c *HTTPClient) {
for k, v := range headers {
c.headers[k] = v
}
}
}
// WithLogging 设置日志记录
func WithLogging(requests, responses bool) ClientOption {
return func(c *HTTPClient) {
c.logRequests = requests
c.logResponses = responses
}
}
// NewHTTPClientWithOptions 使用函数式选项创建客户端
func NewHTTPClientWithOptions(options ...ClientOption) *HTTPClient {
client := &HTTPClient{
baseURL: "http://localhost",
timeout: 30 * time.Second,
retryCount: 3,
retryDelay: 1 * time.Second,
userAgent: "Go-HTTP-Client/1.0",
headers: make(map[string]string),
cookies: make(map[string]string),
followRedirect: true,
maxRedirects: 10,
compression: true,
keepAlive: true,
maxIdleConns: 100,
}
for _, option := range options {
option(client)
}
return client
}
func main() {
fmt.Println("=== Builder Pattern in Go ===")
// 使用建造者模式
fmt.Println("\n1. Using Builder Pattern:")
fmt.Println(strings.Repeat("-", 40))
// 开发环境客户端
devClient, err := ForDevelopment().
BaseURL("http://dev-api.example.com").
UserAgent("MyApp-Dev/1.0").
Header("X-API-Key", "dev-api-key").
Cookie("session", "dev-session-123").
Build()
if err != nil {
fmt.Printf("Error creating dev client: %v\n", err)
return
}
fmt.Println("Development Client:")
fmt.Println(devClient)
fmt.Println()
// 生产环境客户端
prodClient, err := ForProduction().
BaseURL("https://api.example.com").
UserAgent("MyApp-Prod/2.0").
Headers(map[string]string{
"X-API-Key": "prod-api-key",
"Content-Type": "application/json",
"Accept": "application/json",
}).
Proxy("http://proxy.company.com:8080").
Build()
if err != nil {
fmt.Printf("Error creating prod client: %v\n", err)
return
}
fmt.Println("Production Client:")
fmt.Println(prodClient)
fmt.Println()
// 测试环境客户端
testClient, err := ForTesting().
BaseURL("http://test-api.example.com").
UserAgent("MyApp-Test/1.0").
TLSSkipVerify(true).
Build()
if err != nil {
fmt.Printf("Error creating test client: %v\n", err)
return
}
fmt.Println("Test Client:")
fmt.Println(testClient)
fmt.Println()
// 使用函数式选项模式
fmt.Println("\n2. Using Functional Options Pattern:")
fmt.Println(strings.Repeat("-", 40))
optionsClient := NewHTTPClientWithOptions(
WithBaseURL("https://api.github.com"),
WithTimeout(15*time.Second),
WithRetry(2, 3*time.Second),
WithUserAgent("GitHub-Client/1.0"),
WithHeaders(map[string]string{
"Accept": "application/vnd.github.v3+json",
"Authorization": "token github-token-123",
}),
WithLogging(true, false),
)
fmt.Println("GitHub API Client (Functional Options):")
fmt.Println(optionsClient)
fmt.Println()
// 自定义配置
customClient, err := NewHTTPClientBuilder().
BaseURL("https://custom-api.example.com").
Timeout(45*time.Second).
Retry(5, 2*time.Second).
UserAgent("CustomApp/3.0").
Header("X-Custom-Header", "custom-value").
Cookie("auth", "custom-auth-token").
Proxy("socks5://proxy.example.com:1080").
TLSSkipVerify(false).
FollowRedirect(true).
MaxRedirects(5).
Compression(true).
KeepAlive(true).
MaxIdleConns(50).
LogRequests(true).
LogResponses(false).
Build()
if err != nil {
fmt.Printf("Error creating custom client: %v\n", err)
return
}
fmt.Println("Custom Client:")
fmt.Println(customClient)
}
4.2 原型模式(Prototype Pattern)
4.2.1 模式定义
原型模式通过克隆现有对象来创建新对象,而不是通过实例化类。
核心思想: - 通过复制现有对象创建新对象 - 避免复杂的初始化过程 - 支持动态配置对象 - 提高对象创建性能
适用场景: - 对象创建成本较高 - 需要创建大量相似对象 - 对象配置复杂 - 运行时确定对象类型
4.2.2 深拷贝与浅拷贝
import copy
import json
from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional
from datetime import datetime, date
import uuid
# 抽象原型接口
class Prototype(ABC):
@abstractmethod
def clone(self) -> 'Prototype':
pass
@abstractmethod
def deep_clone(self) -> 'Prototype':
pass
# 地址类(用于演示深拷贝和浅拷贝的区别)
class Address:
def __init__(self, street: str, city: str, country: str, postal_code: str):
self.street = street
self.city = city
self.country = country
self.postal_code = postal_code
def __str__(self) -> str:
return f"{self.street}, {self.city}, {self.country} {self.postal_code}"
def __repr__(self) -> str:
return f"Address('{self.street}', '{self.city}', '{self.country}', '{self.postal_code}')"
def clone(self) -> 'Address':
return Address(self.street, self.city, self.country, self.postal_code)
# 联系人类
class Contact:
def __init__(self, name: str, email: str, phone: str):
self.name = name
self.email = email
self.phone = phone
def __str__(self) -> str:
return f"{self.name} ({self.email}, {self.phone})"
def __repr__(self) -> str:
return f"Contact('{self.name}', '{self.email}', '{self.phone}')"
def clone(self) -> 'Contact':
return Contact(self.name, self.email, self.phone)
# 员工类(具体原型)
class Employee(Prototype):
def __init__(self, employee_id: str, name: str, department: str,
position: str, salary: float, hire_date: date,
address: Address, emergency_contact: Contact):
self.employee_id = employee_id
self.name = name
self.department = department
self.position = position
self.salary = salary
self.hire_date = hire_date
self.address = address # 引用类型
self.emergency_contact = emergency_contact # 引用类型
self.skills: List[str] = [] # 可变对象
self.projects: List[Dict[str, Any]] = [] # 复杂嵌套对象
self.metadata: Dict[str, Any] = {} # 元数据
self.created_at = datetime.now()
def add_skill(self, skill: str):
if skill not in self.skills:
self.skills.append(skill)
def add_project(self, project_name: str, role: str, start_date: date, end_date: Optional[date] = None):
project = {
'name': project_name,
'role': role,
'start_date': start_date,
'end_date': end_date,
'status': 'active' if end_date is None else 'completed'
}
self.projects.append(project)
def set_metadata(self, key: str, value: Any):
self.metadata[key] = value
def clone(self) -> 'Employee':
"""浅拷贝:只复制对象本身,引用类型仍然指向原对象"""
cloned = Employee(
self.employee_id,
self.name,
self.department,
self.position,
self.salary,
self.hire_date,
self.address, # 浅拷贝:仍然指向同一个Address对象
self.emergency_contact # 浅拷贝:仍然指向同一个Contact对象
)
cloned.skills = self.skills # 浅拷贝:指向同一个列表
cloned.projects = self.projects # 浅拷贝:指向同一个列表
cloned.metadata = self.metadata # 浅拷贝:指向同一个字典
cloned.created_at = self.created_at
return cloned
def deep_clone(self) -> 'Employee':
"""深拷贝:递归复制所有对象,包括引用类型"""
cloned = Employee(
self.employee_id,
self.name,
self.department,
self.position,
self.salary,
self.hire_date,
self.address.clone(), # 深拷贝:创建新的Address对象
self.emergency_contact.clone() # 深拷贝:创建新的Contact对象
)
cloned.skills = self.skills.copy() # 深拷贝:创建新的列表
cloned.projects = copy.deepcopy(self.projects) # 深拷贝:递归复制嵌套对象
cloned.metadata = copy.deepcopy(self.metadata) # 深拷贝:递归复制字典
cloned.created_at = self.created_at
return cloned
def __str__(self) -> str:
return (f"Employee(ID: {self.employee_id}, Name: {self.name}, "
f"Dept: {self.department}, Position: {self.position}, "
f"Salary: ${self.salary:,.2f})")
def __repr__(self) -> str:
return self.__str__()
def detailed_info(self) -> str:
"""返回详细信息"""
info = []
info.append(f"Employee ID: {self.employee_id}")
info.append(f"Name: {self.name}")
info.append(f"Department: {self.department}")
info.append(f"Position: {self.position}")
info.append(f"Salary: ${self.salary:,.2f}")
info.append(f"Hire Date: {self.hire_date}")
info.append(f"Address: {self.address}")
info.append(f"Emergency Contact: {self.emergency_contact}")
info.append(f"Skills: {', '.join(self.skills) if self.skills else 'None'}")
info.append(f"Projects: {len(self.projects)}")
for i, project in enumerate(self.projects, 1):
info.append(f" {i}. {project['name']} ({project['role']}) - {project['status']}")
info.append(f"Metadata: {len(self.metadata)} items")
info.append(f"Created At: {self.created_at}")
info.append(f"Object ID: {id(self)}")
info.append(f"Address Object ID: {id(self.address)}")
info.append(f"Contact Object ID: {id(self.emergency_contact)}")
info.append(f"Skills List ID: {id(self.skills)}")
info.append(f"Projects List ID: {id(self.projects)}")
return "\n".join(info)
# 原型管理器
class EmployeePrototypeManager:
def __init__(self):
self._prototypes: Dict[str, Employee] = {}
self._initialize_prototypes()
def _initialize_prototypes(self):
"""初始化常用的员工原型"""
# 软件工程师原型
engineer_address = Address("123 Tech Street", "San Francisco", "USA", "94105")
engineer_contact = Contact("Jane Doe", "jane.doe@example.com", "+1-555-0123")
engineer = Employee(
"ENG-001",
"John Engineer",
"Engineering",
"Software Engineer",
95000.0,
date(2023, 1, 15),
engineer_address,
engineer_contact
)
engineer.add_skill("Python")
engineer.add_skill("JavaScript")
engineer.add_skill("React")
engineer.add_skill("Node.js")
engineer.add_project("E-commerce Platform", "Backend Developer", date(2023, 2, 1))
engineer.set_metadata("performance_rating", "A")
engineer.set_metadata("security_clearance", "Level 2")
# 产品经理原型
pm_address = Address("456 Business Ave", "New York", "USA", "10001")
pm_contact = Contact("Bob Smith", "bob.smith@example.com", "+1-555-0456")
pm = Employee(
"PM-001",
"Alice Manager",
"Product",
"Product Manager",
110000.0,
date(2022, 8, 1),
pm_address,
pm_contact
)
pm.add_skill("Product Strategy")
pm.add_skill("Agile/Scrum")
pm.add_skill("Data Analysis")
pm.add_skill("User Research")
pm.add_project("Mobile App Redesign", "Product Owner", date(2022, 9, 1), date(2023, 3, 1))
pm.add_project("Customer Analytics Dashboard", "Product Manager", date(2023, 4, 1))
pm.set_metadata("performance_rating", "A+")
pm.set_metadata("team_size", 8)
# 设计师原型
designer_address = Address("789 Creative Blvd", "Los Angeles", "USA", "90210")
designer_contact = Contact("Carol Designer", "carol.designer@example.com", "+1-555-0789")
designer = Employee(
"DES-001",
"David Designer",
"Design",
"UX/UI Designer",
85000.0,
date(2023, 3, 1),
designer_address,
designer_contact
)
designer.add_skill("Figma")
designer.add_skill("Adobe Creative Suite")
designer.add_skill("User Research")
designer.add_skill("Prototyping")
designer.add_project("Website Redesign", "Lead Designer", date(2023, 4, 1))
designer.set_metadata("portfolio_url", "https://daviddesigner.portfolio.com")
designer.set_metadata("design_awards", ["UX Design Award 2023"])
# 注册原型
self._prototypes["software_engineer"] = engineer
self._prototypes["product_manager"] = pm
self._prototypes["designer"] = designer
def register_prototype(self, name: str, prototype: Employee):
"""注册新的原型"""
self._prototypes[name] = prototype
print(f"Registered prototype: {name}")
def get_prototype(self, name: str) -> Optional[Employee]:
"""获取原型(浅拷贝)"""
prototype = self._prototypes.get(name)
return prototype.clone() if prototype else None
def get_deep_prototype(self, name: str) -> Optional[Employee]:
"""获取原型(深拷贝)"""
prototype = self._prototypes.get(name)
return prototype.deep_clone() if prototype else None
def list_prototypes(self) -> List[str]:
"""列出所有可用的原型"""
return list(self._prototypes.keys())
def create_employee_from_prototype(self, prototype_name: str,
employee_id: str, name: str,
salary: Optional[float] = None,
deep_copy: bool = True) -> Optional[Employee]:
"""基于原型创建新员工"""
if deep_copy:
employee = self.get_deep_prototype(prototype_name)
else:
employee = self.get_prototype(prototype_name)
if employee:
employee.employee_id = employee_id
employee.name = name
if salary is not None:
employee.salary = salary
employee.created_at = datetime.now()
return employee
return None
# 使用示例和对比演示
def demonstrate_prototype_pattern():
print("=== Prototype Pattern Demo ===")
# 创建原型管理器
manager = EmployeePrototypeManager()
print(f"Available prototypes: {manager.list_prototypes()}")
print()
# 演示浅拷贝 vs 深拷贝
print("\n1. Shallow Copy vs Deep Copy Demonstration:")
print("-" * 50)
# 获取原始原型
original = manager._prototypes["software_engineer"]
print("Original Employee:")
print(original.detailed_info())
print()
# 浅拷贝
shallow_copy = original.clone()
shallow_copy.employee_id = "ENG-002"
shallow_copy.name = "Jane Shallow"
shallow_copy.salary = 100000.0
print("Shallow Copy Employee:")
print(shallow_copy.detailed_info())
print()
# 深拷贝
deep_copy = original.deep_clone()
deep_copy.employee_id = "ENG-003"
deep_copy.name = "Bob Deep"
deep_copy.salary = 105000.0
print("Deep Copy Employee:")
print(deep_copy.detailed_info())
print()
# 修改原始对象的引用类型属性
print("\n2. Modifying Original Object's Reference Properties:")
print("-" * 50)
print("Before modification:")
print(f"Original address: {original.address}")
print(f"Shallow copy address: {shallow_copy.address}")
print(f"Deep copy address: {deep_copy.address}")
print()
# 修改原始对象的地址
original.address.street = "999 Modified Street"
original.skills.append("Docker") # 修改技能列表
print("After modifying original object:")
print(f"Original address: {original.address}")
print(f"Shallow copy address: {shallow_copy.address}")
print(f"Deep copy address: {deep_copy.address}")
print()
print(f"Original skills: {original.skills}")
print(f"Shallow copy skills: {shallow_copy.skills}")
print(f"Deep copy skills: {deep_copy.skills}")
print()
print("Analysis:")
print("- Shallow copy shares the same address object (modified)")
print("- Shallow copy shares the same skills list (modified)")
print("- Deep copy has its own address object (unchanged)")
print("- Deep copy has its own skills list (unchanged)")
print()
# 使用原型管理器创建新员工
print("\n3. Creating New Employees from Prototypes:")
print("-" * 50)
# 创建软件工程师
engineer1 = manager.create_employee_from_prototype(
"software_engineer", "ENG-101", "Alice Johnson", 98000.0
)
engineer2 = manager.create_employee_from_prototype(
"software_engineer", "ENG-102", "Charlie Brown", 102000.0
)
# 创建产品经理
pm1 = manager.create_employee_from_prototype(
"product_manager", "PM-101", "Diana Prince", 115000.0
)
# 创建设计师
designer1 = manager.create_employee_from_prototype(
"designer", "DES-101", "Eve Wilson", 88000.0
)
employees = [engineer1, engineer2, pm1, designer1]
for emp in employees:
if emp:
print(f"Created: {emp}")
# 为每个员工添加一些个性化信息
if "ENG" in emp.employee_id:
emp.add_skill("Kubernetes")
emp.add_project("Microservices Migration", "Senior Developer", date(2023, 6, 1))
elif "PM" in emp.employee_id:
emp.add_skill("Stakeholder Management")
emp.add_project("Product Roadmap 2024", "Product Owner", date(2023, 7, 1))
elif "DES" in emp.employee_id:
emp.add_skill("Design Systems")
emp.add_project("Design System v2", "Design Lead", date(2023, 8, 1))
print()
# 性能对比:创建大量对象
print("\n4. Performance Comparison:")
print("-" * 50)
import time
# 测试原型模式性能
start_time = time.time()
prototype_employees = []
for i in range(1000):
emp = manager.create_employee_from_prototype(
"software_engineer", f"ENG-{i:04d}", f"Employee {i}", 95000.0 + i * 100
)
if emp:
prototype_employees.append(emp)
prototype_time = time.time() - start_time
# 测试直接创建对象的性能
start_time = time.time()
direct_employees = []
for i in range(1000):
address = Address("123 Tech Street", "San Francisco", "USA", "94105")
contact = Contact("Jane Doe", "jane.doe@example.com", "+1-555-0123")
emp = Employee(
f"ENG-{i:04d}",
f"Employee {i}",
"Engineering",
"Software Engineer",
95000.0 + i * 100,
date(2023, 1, 15),
address,
contact
)
emp.add_skill("Python")
emp.add_skill("JavaScript")
emp.add_skill("React")
emp.add_skill("Node.js")
direct_employees.append(emp)
direct_time = time.time() - start_time
print(f"Creating 1000 employees using prototype pattern: {prototype_time:.4f} seconds")
print(f"Creating 1000 employees directly: {direct_time:.4f} seconds")
print(f"Prototype pattern is {direct_time/prototype_time:.2f}x faster")
print()
# 内存使用对比
print("\n5. Memory Usage Analysis:")
print("-" * 50)
# 浅拷贝:共享引用对象
shallow_employees = []
for i in range(5):
emp = manager.get_prototype("software_engineer")
if emp:
emp.employee_id = f"SHALLOW-{i:02d}"
emp.name = f"Shallow Employee {i}"
shallow_employees.append(emp)
# 深拷贝:独立对象
deep_employees = []
for i in range(5):
emp = manager.get_deep_prototype("software_engineer")
if emp:
emp.employee_id = f"DEEP-{i:02d}"
emp.name = f"Deep Employee {i}"
deep_employees.append(emp)
print("Shallow Copy - Address Object IDs:")
for emp in shallow_employees:
print(f" {emp.name}: {id(emp.address)}")
print("\nDeep Copy - Address Object IDs:")
for emp in deep_employees:
print(f" {emp.name}: {id(emp.address)}")
print("\nAnalysis:")
print("- Shallow copies share the same address objects (same IDs)")
print("- Deep copies have unique address objects (different IDs)")
print("- Shallow copy saves memory but changes affect all copies")
print("- Deep copy uses more memory but provides complete isolation")
if __name__ == "__main__":
demonstrate_prototype_pattern()
4.2.3 Go语言实现
package main
import (
"encoding/json"
"fmt"
"log"
"reflect"
"time"
)
// Cloneable 接口定义克隆方法
type Cloneable interface {
Clone() Cloneable
DeepClone() Cloneable
}
// Address 地址结构体
type Address struct {
Street string `json:"street"`
City string `json:"city"`
Country string `json:"country"`
ZipCode string `json:"zip_code"`
}
// Clone 浅拷贝
func (a *Address) Clone() *Address {
return &Address{
Street: a.Street,
City: a.City,
Country: a.Country,
ZipCode: a.ZipCode,
}
}
// DeepClone 深拷贝(对于Address来说与浅拷贝相同)
func (a *Address) DeepClone() *Address {
return a.Clone()
}
func (a *Address) String() string {
return fmt.Sprintf("%s, %s, %s %s", a.Street, a.City, a.Country, a.ZipCode)
}
// Contact 联系信息结构体
type Contact struct {
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
}
// Clone 浅拷贝
func (c *Contact) Clone() *Contact {
return &Contact{
Name: c.Name,
Email: c.Email,
Phone: c.Phone,
}
}
// DeepClone 深拷贝
func (c *Contact) DeepClone() *Contact {
return c.Clone()
}
func (c *Contact) String() string {
return fmt.Sprintf("%s <%s> %s", c.Name, c.Email, c.Phone)
}
// Employee 员工结构体
type Employee struct {
EmployeeID string `json:"employee_id"`
Name string `json:"name"`
Department string `json:"department"`
Position string `json:"position"`
Salary float64 `json:"salary"`
HireDate time.Time `json:"hire_date"`
Address *Address `json:"address"`
Contact *Contact `json:"contact"`
Skills []string `json:"skills"`
Projects []Project `json:"projects"`
Metadata map[string]interface{} `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
}
// Project 项目结构体
type Project struct {
Name string `json:"name"`
Role string `json:"role"`
StartDate time.Time `json:"start_date"`
EndDate *time.Time `json:"end_date,omitempty"`
}
// NewEmployee 创建新员工
func NewEmployee(id, name, department, position string, salary float64, hireDate time.Time, address *Address, contact *Contact) *Employee {
return &Employee{
EmployeeID: id,
Name: name,
Department: department,
Position: position,
Salary: salary,
HireDate: hireDate,
Address: address,
Contact: contact,
Skills: make([]string, 0),
Projects: make([]Project, 0),
Metadata: make(map[string]interface{}),
CreatedAt: time.Now(),
}
}
// AddSkill 添加技能
func (e *Employee) AddSkill(skill string) {
e.Skills = append(e.Skills, skill)
}
// AddProject 添加项目
func (e *Employee) AddProject(name, role string, startDate time.Time, endDate *time.Time) {
project := Project{
Name: name,
Role: role,
StartDate: startDate,
EndDate: endDate,
}
e.Projects = append(e.Projects, project)
}
// SetMetadata 设置元数据
func (e *Employee) SetMetadata(key string, value interface{}) {
e.Metadata[key] = value
}
// Clone 浅拷贝(共享引用类型)
func (e *Employee) Clone() Cloneable {
// 浅拷贝:共享Address、Contact、Skills、Projects、Metadata
cloned := &Employee{
EmployeeID: e.EmployeeID,
Name: e.Name,
Department: e.Department,
Position: e.Position,
Salary: e.Salary,
HireDate: e.HireDate,
Address: e.Address, // 共享同一个Address对象
Contact: e.Contact, // 共享同一个Contact对象
Skills: e.Skills, // 共享同一个slice
Projects: e.Projects, // 共享同一个slice
Metadata: e.Metadata, // 共享同一个map
CreatedAt: time.Now(),
}
return cloned
}
// DeepClone 深拷贝(创建独立副本)
func (e *Employee) DeepClone() Cloneable {
// 深拷贝Address
var clonedAddress *Address
if e.Address != nil {
clonedAddress = e.Address.DeepClone()
}
// 深拷贝Contact
var clonedContact *Contact
if e.Contact != nil {
clonedContact = e.Contact.DeepClone()
}
// 深拷贝Skills
clonedSkills := make([]string, len(e.Skills))
copy(clonedSkills, e.Skills)
// 深拷贝Projects
clonedProjects := make([]Project, len(e.Projects))
for i, project := range e.Projects {
clonedProject := Project{
Name: project.Name,
Role: project.Role,
StartDate: project.StartDate,
}
if project.EndDate != nil {
endDate := *project.EndDate
clonedProject.EndDate = &endDate
}
clonedProjects[i] = clonedProject
}
// 深拷贝Metadata
clonedMetadata := make(map[string]interface{})
for k, v := range e.Metadata {
// 对于复杂类型,这里简化处理
// 实际应用中可能需要更复杂的深拷贝逻辑
clonedMetadata[k] = v
}
cloned := &Employee{
EmployeeID: e.EmployeeID,
Name: e.Name,
Department: e.Department,
Position: e.Position,
Salary: e.Salary,
HireDate: e.HireDate,
Address: clonedAddress,
Contact: clonedContact,
Skills: clonedSkills,
Projects: clonedProjects,
Metadata: clonedMetadata,
CreatedAt: time.Now(),
}
return cloned
}
// String 字符串表示
func (e *Employee) String() string {
return fmt.Sprintf("Employee{ID: %s, Name: %s, Position: %s, Department: %s, Salary: %.2f}",
e.EmployeeID, e.Name, e.Position, e.Department, e.Salary)
}
// DetailedInfo 详细信息
func (e *Employee) DetailedInfo() string {
info := fmt.Sprintf("Employee Details:\n")
info += fmt.Sprintf(" ID: %s\n", e.EmployeeID)
info += fmt.Sprintf(" Name: %s\n", e.Name)
info += fmt.Sprintf(" Department: %s\n", e.Department)
info += fmt.Sprintf(" Position: %s\n", e.Position)
info += fmt.Sprintf(" Salary: $%.2f\n", e.Salary)
info += fmt.Sprintf(" Hire Date: %s\n", e.HireDate.Format("2006-01-02"))
info += fmt.Sprintf(" Created At: %s\n", e.CreatedAt.Format("2006-01-02 15:04:05"))
if e.Address != nil {
info += fmt.Sprintf(" Address: %s\n", e.Address)
}
if e.Contact != nil {
info += fmt.Sprintf(" Contact: %s\n", e.Contact)
}
if len(e.Skills) > 0 {
info += fmt.Sprintf(" Skills: %v\n", e.Skills)
}
if len(e.Projects) > 0 {
info += fmt.Sprintf(" Projects: %d\n", len(e.Projects))
for i, project := range e.Projects {
endDateStr := "ongoing"
if project.EndDate != nil {
endDateStr = project.EndDate.Format("2006-01-02")
}
info += fmt.Sprintf(" %d. %s (%s) [%s - %s]\n",
i+1, project.Name, project.Role,
project.StartDate.Format("2006-01-02"), endDateStr)
}
}
if len(e.Metadata) > 0 {
info += fmt.Sprintf(" Metadata: %v\n", e.Metadata)
}
return info
}
// EmployeePrototypeManager 员工原型管理器
type EmployeePrototypeManager struct {
prototypes map[string]*Employee
}
// NewEmployeePrototypeManager 创建原型管理器
func NewEmployeePrototypeManager() *EmployeePrototypeManager {
manager := &EmployeePrototypeManager{
prototypes: make(map[string]*Employee),
}
manager.initializePrototypes()
return manager
}
// initializePrototypes 初始化默认原型
func (m *EmployeePrototypeManager) initializePrototypes() {
// 软件工程师原型
engineerAddress := &Address{"123 Tech Street", "San Francisco", "USA", "94105"}
engineerContact := &Contact{"Jane Doe", "jane.doe@example.com", "+1-555-0123"}
engineer := NewEmployee(
"ENG-001",
"John Engineer",
"Engineering",
"Software Engineer",
95000.0,
time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
engineerAddress,
engineerContact,
)
engineer.AddSkill("Python")
engineer.AddSkill("JavaScript")
engineer.AddSkill("React")
engineer.AddSkill("Node.js")
engineer.AddProject("E-commerce Platform", "Full Stack Developer", time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC), nil)
engineer.SetMetadata("certification", "AWS Certified Developer")
engineer.SetMetadata("years_experience", 5)
// 产品经理原型
pmAddress := &Address{"456 Business Ave", "New York", "USA", "10001"}
pmContact := &Contact{"Bob Manager", "bob.manager@example.com", "+1-555-0456"}
pm := NewEmployee(
"PM-001",
"Alice ProductManager",
"Product",
"Senior Product Manager",
110000.0,
time.Date(2022, 6, 1, 0, 0, 0, 0, time.UTC),
pmAddress,
pmContact,
)
pm.AddSkill("Product Strategy")
pm.AddSkill("Agile Methodology")
pm.AddSkill("Data Analysis")
pm.AddSkill("User Research")
endDate := time.Date(2023, 3, 1, 0, 0, 0, 0, time.UTC)
pm.AddProject("Mobile App Redesign", "Product Owner", time.Date(2022, 9, 1, 0, 0, 0, 0, time.UTC), &endDate)
pm.AddProject("Customer Analytics Dashboard", "Product Manager", time.Date(2023, 4, 1, 0, 0, 0, 0, time.UTC), nil)
pm.SetMetadata("performance_rating", "A+")
pm.SetMetadata("team_size", 8)
// 设计师原型
designerAddress := &Address{"789 Creative Blvd", "Los Angeles", "USA", "90210"}
designerContact := &Contact{"Carol Designer", "carol.designer@example.com", "+1-555-0789"}
designer := NewEmployee(
"DES-001",
"David Designer",
"Design",
"UX/UI Designer",
85000.0,
time.Date(2023, 3, 1, 0, 0, 0, 0, time.UTC),
designerAddress,
designerContact,
)
designer.AddSkill("Figma")
designer.AddSkill("Adobe Creative Suite")
designer.AddSkill("User Research")
designer.AddSkill("Prototyping")
designer.AddProject("Website Redesign", "Lead Designer", time.Date(2023, 4, 1, 0, 0, 0, 0, time.UTC), nil)
designer.SetMetadata("portfolio_url", "https://daviddesigner.portfolio.com")
designer.SetMetadata("design_awards", []string{"UX Design Award 2023"})
// 注册原型
m.prototypes["software_engineer"] = engineer
m.prototypes["product_manager"] = pm
m.prototypes["designer"] = designer
}
// RegisterPrototype 注册新原型
func (m *EmployeePrototypeManager) RegisterPrototype(name string, prototype *Employee) {
m.prototypes[name] = prototype
fmt.Printf("Registered prototype: %s\n", name)
}
// GetPrototype 获取原型(浅拷贝)
func (m *EmployeePrototypeManager) GetPrototype(name string) *Employee {
if prototype, exists := m.prototypes[name]; exists {
return prototype.Clone().(*Employee)
}
return nil
}
// GetDeepPrototype 获取原型(深拷贝)
func (m *EmployeePrototypeManager) GetDeepPrototype(name string) *Employee {
if prototype, exists := m.prototypes[name]; exists {
return prototype.DeepClone().(*Employee)
}
return nil
}
// ListPrototypes 列出所有可用原型
func (m *EmployeePrototypeManager) ListPrototypes() []string {
keys := make([]string, 0, len(m.prototypes))
for key := range m.prototypes {
keys = append(keys, key)
}
return keys
}
// CreateEmployeeFromPrototype 基于原型创建新员工
func (m *EmployeePrototypeManager) CreateEmployeeFromPrototype(prototypeName, employeeID, name string, salary *float64, deepCopy bool) *Employee {
var employee *Employee
if deepCopy {
employee = m.GetDeepPrototype(prototypeName)
} else {
employee = m.GetPrototype(prototypeName)
}
if employee != nil {
employee.EmployeeID = employeeID
employee.Name = name
if salary != nil {
employee.Salary = *salary
}
employee.CreatedAt = time.Now()
return employee
}
return nil
}
// demonstratePrototypePattern 演示原型模式
func demonstratePrototypePattern() {
fmt.Println("=== Prototype Pattern Demo ===")
// 创建原型管理器
manager := NewEmployeePrototypeManager()
fmt.Printf("Available prototypes: %v\n", manager.ListPrototypes())
fmt.Println()
// 演示浅拷贝 vs 深拷贝
fmt.Println("\n1. Shallow Copy vs Deep Copy Demonstration:")
fmt.Println(strings.Repeat("-", 50))
// 获取原始原型
original := manager.prototypes["software_engineer"]
fmt.Println("Original Employee:")
fmt.Println(original.DetailedInfo())
fmt.Println()
// 浅拷贝
shallowCopy := original.Clone().(*Employee)
shallowCopy.EmployeeID = "ENG-002"
shallowCopy.Name = "Jane Shallow"
shallowCopy.Salary = 100000.0
fmt.Println("Shallow Copy Employee:")
fmt.Println(shallowCopy.DetailedInfo())
fmt.Println()
// 深拷贝
deepCopy := original.DeepClone().(*Employee)
deepCopy.EmployeeID = "ENG-003"
deepCopy.Name = "Bob Deep"
deepCopy.Salary = 105000.0
fmt.Println("Deep Copy Employee:")
fmt.Println(deepCopy.DetailedInfo())
fmt.Println()
// 修改原始对象的引用类型属性
fmt.Println("\n2. Modifying Original Object's Reference Properties:")
fmt.Println(strings.Repeat("-", 50))
fmt.Println("Before modification:")
fmt.Printf("Original address: %s (ptr: %p)\n", original.Address, original.Address)
fmt.Printf("Shallow copy address: %s (ptr: %p)\n", shallowCopy.Address, shallowCopy.Address)
fmt.Printf("Deep copy address: %s (ptr: %p)\n", deepCopy.Address, deepCopy.Address)
fmt.Println()
// 修改原始对象的地址
original.Address.Street = "999 Modified Street"
original.AddSkill("Docker") // 修改技能列表
fmt.Println("After modifying original object:")
fmt.Printf("Original address: %s (ptr: %p)\n", original.Address, original.Address)
fmt.Printf("Shallow copy address: %s (ptr: %p)\n", shallowCopy.Address, shallowCopy.Address)
fmt.Printf("Deep copy address: %s (ptr: %p)\n", deepCopy.Address, deepCopy.Address)
fmt.Println()
fmt.Printf("Original skills: %v\n", original.Skills)
fmt.Printf("Shallow copy skills: %v\n", shallowCopy.Skills)
fmt.Printf("Deep copy skills: %v\n", deepCopy.Skills)
fmt.Println()
fmt.Println("Analysis:")
fmt.Println("- Shallow copy shares the same address object (same pointer)")
fmt.Println("- Shallow copy shares the same skills slice (same pointer)")
fmt.Println("- Deep copy has its own address object (different pointer)")
fmt.Println("- Deep copy has its own skills slice (different pointer)")
fmt.Println()
// 使用原型管理器创建新员工
fmt.Println("\n3. Creating New Employees from Prototypes:")
fmt.Println(strings.Repeat("-", 50))
// 创建软件工程师
salary1 := 98000.0
engineer1 := manager.CreateEmployeeFromPrototype("software_engineer", "ENG-101", "Alice Johnson", &salary1, true)
salary2 := 102000.0
engineer2 := manager.CreateEmployeeFromPrototype("software_engineer", "ENG-102", "Charlie Brown", &salary2, true)
// 创建产品经理
salary3 := 115000.0
pm1 := manager.CreateEmployeeFromPrototype("product_manager", "PM-101", "Diana Prince", &salary3, true)
// 创建设计师
salary4 := 88000.0
designer1 := manager.CreateEmployeeFromPrototype("designer", "DES-101", "Eve Wilson", &salary4, true)
employees := []*Employee{engineer1, engineer2, pm1, designer1}
for _, emp := range employees {
if emp != nil {
fmt.Printf("Created: %s\n", emp)
// 为每个员工添加一些个性化信息
if strings.Contains(emp.EmployeeID, "ENG") {
emp.AddSkill("Kubernetes")
emp.AddProject("Microservices Migration", "Senior Developer", time.Date(2023, 6, 1, 0, 0, 0, 0, time.UTC), nil)
} else if strings.Contains(emp.EmployeeID, "PM") {
emp.AddSkill("Stakeholder Management")
emp.AddProject("Product Roadmap 2024", "Product Owner", time.Date(2023, 7, 1, 0, 0, 0, 0, time.UTC), nil)
} else if strings.Contains(emp.EmployeeID, "DES") {
emp.AddSkill("Design Systems")
emp.AddProject("Design System v2", "Design Lead", time.Date(2023, 8, 1, 0, 0, 0, 0, time.UTC), nil)
}
}
}
fmt.Println()
// 性能对比:创建大量对象
fmt.Println("\n4. Performance Comparison:")
fmt.Println(strings.Repeat("-", 50))
// 测试原型模式性能
startTime := time.Now()
prototypeEmployees := make([]*Employee, 0, 1000)
for i := 0; i < 1000; i++ {
salary := 95000.0 + float64(i*100)
emp := manager.CreateEmployeeFromPrototype("software_engineer", fmt.Sprintf("ENG-%04d", i), fmt.Sprintf("Employee %d", i), &salary, true)
if emp != nil {
prototypeEmployees = append(prototypeEmployees, emp)
}
}
prototypeTime := time.Since(startTime)
// 测试直接创建对象的性能
startTime = time.Now()
directEmployees := make([]*Employee, 0, 1000)
for i := 0; i < 1000; i++ {
address := &Address{"123 Tech Street", "San Francisco", "USA", "94105"}
contact := &Contact{"Jane Doe", "jane.doe@example.com", "+1-555-0123"}
emp := NewEmployee(
fmt.Sprintf("ENG-%04d", i),
fmt.Sprintf("Employee %d", i),
"Engineering",
"Software Engineer",
95000.0+float64(i*100),
time.Date(2023, 1, 15, 0, 0, 0, 0, time.UTC),
address,
contact,
)
emp.AddSkill("Python")
emp.AddSkill("JavaScript")
emp.AddSkill("React")
emp.AddSkill("Node.js")
directEmployees = append(directEmployees, emp)
}
directTime := time.Since(startTime)
fmt.Printf("Creating 1000 employees using prototype pattern: %v\n", prototypeTime)
fmt.Printf("Creating 1000 employees directly: %v\n", directTime)
if prototypeTime > 0 {
fmt.Printf("Direct creation is %.2fx faster\n", float64(prototypeTime)/float64(directTime))
}
fmt.Println()
// 内存使用对比
fmt.Println("\n5. Memory Usage Analysis:")
fmt.Println(strings.Repeat("-", 50))
// 浅拷贝:共享引用对象
shallowEmployees := make([]*Employee, 0, 5)
for i := 0; i < 5; i++ {
emp := manager.GetPrototype("software_engineer")
if emp != nil {
emp.EmployeeID = fmt.Sprintf("SHALLOW-%02d", i)
emp.Name = fmt.Sprintf("Shallow Employee %d", i)
shallowEmployees = append(shallowEmployees, emp)
}
}
// 深拷贝:独立对象
deepEmployees := make([]*Employee, 0, 5)
for i := 0; i < 5; i++ {
emp := manager.GetDeepPrototype("software_engineer")
if emp != nil {
emp.EmployeeID = fmt.Sprintf("DEEP-%02d", i)
emp.Name = fmt.Sprintf("Deep Employee %d", i)
deepEmployees = append(deepEmployees, emp)
}
}
fmt.Println("Shallow Copy - Address Object Pointers:")
for _, emp := range shallowEmployees {
fmt.Printf(" %s: %p\n", emp.Name, emp.Address)
}
fmt.Println("\nDeep Copy - Address Object Pointers:")
for _, emp := range deepEmployees {
fmt.Printf(" %s: %p\n", emp.Name, emp.Address)
}
fmt.Println("\nAnalysis:")
fmt.Println("- Shallow copies share the same address objects (same pointers)")
fmt.Println("- Deep copies have unique address objects (different pointers)")
fmt.Println("- Shallow copy saves memory but changes affect all copies")
fmt.Println("- Deep copy uses more memory but provides complete isolation")
}
func main() {
demonstratePrototypePattern()
}
4.3 建造者模式与原型模式对比分析
4.3.1 设计目的对比
方面 | 建造者模式 | 原型模式 |
---|---|---|
主要目的 | 构建复杂对象 | 克隆现有对象 |
创建方式 | 逐步构建 | 基于原型复制 |
适用场景 | 对象构造复杂、参数众多 | 对象创建成本高、需要大量相似对象 |
性能特点 | 构建过程可控,但可能较慢 | 克隆通常比重新创建快 |
灵活性 | 高度可定制化 | 基于现有模板,定制化程度中等 |
内存使用 | 每次创建新对象 | 浅拷贝节省内存,深拷贝消耗更多 |
复杂度 | 实现相对复杂 | 实现相对简单 |
4.3.2 使用场景对比
建造者模式适用于: - 创建复杂对象,具有多个可选参数 - 对象创建过程需要多个步骤 - 需要创建不同表示的同一类对象 - 构造过程必须允许被构造的对象有不同的表示
原型模式适用于: - 对象的创建成本比较大(如需要访问数据库、网络等) - 系统需要大量相似对象 - 对象的初始化需要消耗大量资源 - 需要避免使用分层次的工厂类来创建分层次的对象
4.3.3 选择指南
# 选择决策树
def choose_pattern(requirements):
"""
根据需求选择合适的创建型模式
"""
if requirements.get('complex_construction'):
if requirements.get('many_optional_parameters'):
return "Builder Pattern"
elif requirements.get('step_by_step_construction'):
return "Builder Pattern"
if requirements.get('expensive_creation'):
if requirements.get('many_similar_objects'):
return "Prototype Pattern"
elif requirements.get('clone_existing_objects'):
return "Prototype Pattern"
if requirements.get('simple_object_creation'):
return "Factory Pattern or Direct Construction"
return "Consider combining multiple patterns"
# 使用示例
requirements_1 = {
'complex_construction': True,
'many_optional_parameters': True,
'expensive_creation': False
}
print(f"Recommendation: {choose_pattern(requirements_1)}") # Builder Pattern
requirements_2 = {
'complex_construction': False,
'expensive_creation': True,
'many_similar_objects': True
}
print(f"Recommendation: {choose_pattern(requirements_2)}") # Prototype Pattern
4.3.4 组合使用
在某些情况下,建造者模式和原型模式可以组合使用:
// Java示例:组合使用建造者模式和原型模式
public class ConfigurableEmployeeBuilder {
private EmployeePrototypeManager prototypeManager;
private Employee baseEmployee;
public ConfigurableEmployeeBuilder(EmployeePrototypeManager manager) {
this.prototypeManager = manager;
}
// 基于原型开始构建
public ConfigurableEmployeeBuilder fromPrototype(String prototypeName) {
this.baseEmployee = prototypeManager.getDeepPrototype(prototypeName);
return this;
}
// 建造者模式的配置方法
public ConfigurableEmployeeBuilder withId(String id) {
this.baseEmployee.setEmployeeId(id);
return this;
}
public ConfigurableEmployeeBuilder withName(String name) {
this.baseEmployee.setName(name);
return this;
}
public ConfigurableEmployeeBuilder withSalary(double salary) {
this.baseEmployee.setSalary(salary);
return this;
}
public ConfigurableEmployeeBuilder addSkill(String skill) {
this.baseEmployee.addSkill(skill);
return this;
}
public ConfigurableEmployeeBuilder withCustomAddress(String street, String city, String country, String zipCode) {
Address customAddress = new Address(street, city, country, zipCode);
this.baseEmployee.setAddress(customAddress);
return this;
}
public Employee build() {
if (baseEmployee == null) {
throw new IllegalStateException("Must call fromPrototype() first");
}
Employee result = baseEmployee;
baseEmployee = null; // 重置以便重用builder
return result;
}
}
// 使用示例
ConfigurableEmployeeBuilder builder = new ConfigurableEmployeeBuilder(prototypeManager);
// 基于软件工程师原型,创建定制化的高级工程师
Employee seniorEngineer = builder
.fromPrototype("software_engineer")
.withId("ENG-SENIOR-001")
.withName("Alice Senior")
.withSalary(150000.0)
.addSkill("System Architecture")
.addSkill("Team Leadership")
.withCustomAddress("456 Innovation Drive", "Seattle", "USA", "98101")
.build();
// 基于产品经理原型,创建定制化的VP
Employee vp = builder
.fromPrototype("product_manager")
.withId("VP-001")
.withName("Bob VP")
.withSalary(200000.0)
.addSkill("Strategic Planning")
.addSkill("Executive Leadership")
.build();
4.4 深拷贝与浅拷贝详解
4.4.1 概念区别
浅拷贝(Shallow Copy): - 创建新对象,但内部的引用类型字段仍指向原对象的相同实例 - 修改引用类型字段会影响原对象 - 内存使用较少,性能较好
深拷贝(Deep Copy): - 创建新对象,同时递归复制所有引用类型字段 - 完全独立的对象副本 - 内存使用较多,性能相对较差
4.4.2 实现策略
Python实现策略
import copy
import json
import pickle
from typing import Any, Dict, List
class DeepCopyStrategies:
"""深拷贝的不同实现策略"""
@staticmethod
def manual_deep_copy(obj: Any) -> Any:
"""手动实现深拷贝"""
if hasattr(obj, 'deep_clone'):
return obj.deep_clone()
elif isinstance(obj, dict):
return {k: DeepCopyStrategies.manual_deep_copy(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [DeepCopyStrategies.manual_deep_copy(item) for item in obj]
elif isinstance(obj, tuple):
return tuple(DeepCopyStrategies.manual_deep_copy(item) for item in obj)
else:
return copy.deepcopy(obj)
@staticmethod
def copy_module_deep_copy(obj: Any) -> Any:
"""使用copy模块的深拷贝"""
return copy.deepcopy(obj)
@staticmethod
def json_deep_copy(obj: Any) -> Any:
"""使用JSON序列化实现深拷贝(限制:只支持JSON可序列化的对象)"""
try:
return json.loads(json.dumps(obj, default=str))
except (TypeError, ValueError) as e:
raise ValueError(f"Object is not JSON serializable: {e}")
@staticmethod
def pickle_deep_copy(obj: Any) -> Any:
"""使用pickle序列化实现深拷贝"""
return pickle.loads(pickle.dumps(obj))
# 性能对比测试
import time
def performance_comparison():
"""比较不同深拷贝策略的性能"""
# 创建测试数据
test_data = {
'numbers': list(range(1000)),
'nested': {
'level1': {
'level2': {
'data': [{'id': i, 'value': f'item_{i}'} for i in range(100)]
}
}
},
'metadata': {
'created_at': '2023-01-01',
'tags': ['tag1', 'tag2', 'tag3'] * 50
}
}
strategies = {
'copy.deepcopy': DeepCopyStrategies.copy_module_deep_copy,
'json_copy': DeepCopyStrategies.json_deep_copy,
'pickle_copy': DeepCopyStrategies.pickle_deep_copy,
}
results = {}
for name, strategy in strategies.items():
start_time = time.time()
try:
for _ in range(100): # 执行100次
copied = strategy(test_data)
end_time = time.time()
results[name] = {
'time': end_time - start_time,
'success': True
}
except Exception as e:
results[name] = {
'time': float('inf'),
'success': False,
'error': str(e)
}
print("Deep Copy Performance Comparison (100 iterations):")
print("-" * 60)
for name, result in results.items():
if result['success']:
print(f"{name:15}: {result['time']:.4f} seconds")
else:
print(f"{name:15}: FAILED - {result['error']}")
if __name__ == "__main__":
performance_comparison()
Java实现策略
// Java深拷贝实现策略
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
public class DeepCopyStrategies {
// 1. 序列化深拷贝
@SuppressWarnings("unchecked")
public static <T extends Serializable> T serializationDeepCopy(T original) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(original);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
T copy = (T) ois.readObject();
ois.close();
return copy;
} catch (Exception e) {
throw new RuntimeException("Serialization deep copy failed", e);
}
}
// 2. 反射深拷贝
@SuppressWarnings("unchecked")
public static <T> T reflectionDeepCopy(T original) {
if (original == null) return null;
try {
Class<?> clazz = original.getClass();
T copy = (T) clazz.getDeclaredConstructor().newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = field.get(original);
if (value != null) {
if (isPrimitive(value.getClass())) {
field.set(copy, value);
} else if (value instanceof String) {
field.set(copy, value); // String是不可变的
} else if (value instanceof List) {
List<?> originalList = (List<?>) value;
List<Object> copyList = new ArrayList<>();
for (Object item : originalList) {
copyList.add(reflectionDeepCopy(item));
}
field.set(copy, copyList);
} else {
field.set(copy, reflectionDeepCopy(value));
}
}
}
return copy;
} catch (Exception e) {
throw new RuntimeException("Reflection deep copy failed", e);
}
}
private static boolean isPrimitive(Class<?> clazz) {
return clazz.isPrimitive() ||
clazz == Boolean.class || clazz == Byte.class ||
clazz == Character.class || clazz == Short.class ||
clazz == Integer.class || clazz == Long.class ||
clazz == Float.class || clazz == Double.class;
}
// 3. 克隆接口深拷贝
public interface DeepCloneable<T> extends Cloneable {
T deepClone();
}
}
4.4.3 选择建议
场景 | 推荐策略 | 原因 |
---|---|---|
性能敏感 | 手动实现 | 最优性能,精确控制 |
简单对象 | copy.deepcopy() | 简单易用,覆盖面广 |
可序列化对象 | 序列化方式 | 实现简单,适用性好 |
复杂嵌套结构 | 手动实现 | 可控制拷贝深度和策略 |
跨语言兼容 | JSON序列化 | 标准格式,易于调试 |
4.5 本章总结
4.5.1 核心概念回顾
建造者模式: - 将复杂对象的构建过程与其表示分离 - 通过链式调用提供流畅的API - 适用于参数众多、构建复杂的对象 - 提高代码可读性和可维护性
原型模式: - 通过克隆现有对象来创建新对象 - 避免重复的初始化工作 - 支持浅拷贝和深拷贝两种策略 - 适用于对象创建成本高的场景
4.5.2 最佳实践
建造者模式最佳实践:
- 使用静态内部类实现Builder
- 提供必需参数的构造函数
- 对可选参数提供默认值
- 在build()方法中进行参数验证
- 考虑线程安全性
原型模式最佳实践:
- 明确区分浅拷贝和深拷贝的使用场景
- 为复杂对象提供专门的克隆方法
- 考虑使用原型注册表管理原型
- 注意循环引用问题
- 性能测试不同拷贝策略
4.5.3 实际应用建议
何时使用建造者模式:
- 配置对象(如数据库连接配置)
- 复杂的查询构建器
- 测试数据构建
- API请求构建
何时使用原型模式:
- 游戏中的角色/道具创建
- 文档模板系统
- 配置对象的复制
- 缓存对象的克隆
4.5.4 注意事项
建造者模式注意事项:
- 避免过度设计,简单对象不需要Builder
- 注意Builder的重用性
- 考虑不可变对象的构建
原型模式注意事项:
- 深拷贝的性能开销
- 循环引用的处理
- 克隆方法的正确实现
- 原型对象的状态管理
4.6 练习题
4.6.1 基础练习
建造者模式练习: 设计一个HTTP请求构建器,支持设置URL、请求方法、请求头、请求体等参数。
原型模式练习: 实现一个图形对象的原型系统,支持圆形、矩形、三角形的克隆。
4.6.2 进阶练习
组合模式练习: 结合建造者模式和原型模式,设计一个游戏角色创建系统。
性能优化练习: 比较不同深拷贝实现的性能,并提出优化建议。
4.6.3 思考题
- 在什么情况下原型模式比工厂模式更合适?
- 如何处理原型模式中的循环引用问题?
- 建造者模式如何与依赖注入框架结合使用?
- 如何设计一个支持版本控制的原型系统?
下一章预告: 第5章将学习结构型设计模式的基础,包括适配器模式、装饰器模式等,探讨如何优雅地组合对象和类。