本章目标

  • 理解创建型设计模式的核心思想
  • 掌握单例模式的多种实现方式
  • 学会使用工厂模式创建对象
  • 理解建造者模式的应用场景
  • 掌握原型模式的克隆机制
  • 学会在实际项目中选择合适的创建型模式

3.1 创建型模式概述

3.1.1 什么是创建型模式

创建型设计模式关注对象的创建过程,它们提供了创建对象的机制,能够提升已有代码的灵活性和可复用性。

核心思想: - 将对象的创建与使用分离 - 隐藏对象创建的复杂性 - 提供灵活的对象创建方式 - 支持对象创建的扩展和变化

3.1.2 创建型模式的分类

  1. 单例模式(Singleton):确保一个类只有一个实例
  2. 工厂方法模式(Factory Method):创建对象的接口,让子类决定实例化哪个类
  3. 抽象工厂模式(Abstract Factory):创建相关对象家族的接口
  4. 建造者模式(Builder):分步骤构建复杂对象
  5. 原型模式(Prototype):通过克隆创建对象

3.1.3 创建型模式的优势

# 不使用创建型模式的问题示例
class DatabaseConnection:
    def __init__(self, host, port, username, password, database):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.database = database
        self.connection = None
    
    def connect(self):
        # 复杂的连接逻辑
        print(f"Connecting to {self.database} at {self.host}:{self.port}")
        self.connection = f"Connected to {self.database}"

# 问题:每次都需要重复创建连接,参数复杂,容易出错
def bad_example():
    # 在多个地方重复创建连接
    db1 = DatabaseConnection("localhost", 5432, "user", "pass", "app_db")
    db1.connect()
    
    db2 = DatabaseConnection("localhost", 5432, "user", "pass", "app_db")
    db2.connect()
    
    # 参数容易写错
    db3 = DatabaseConnection("localhost", 5432, "user", "wrong_pass", "app_db")
    db3.connect()

# 使用创建型模式的改进
class DatabaseConnectionManager:
    _instance = None
    _connection = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def get_connection(self):
        if self._connection is None:
            self._connection = DatabaseConnection(
                "localhost", 5432, "user", "pass", "app_db"
            )
            self._connection.connect()
        return self._connection

# 改进后:统一管理,避免重复创建
def good_example():
    manager1 = DatabaseConnectionManager()
    conn1 = manager1.get_connection()
    
    manager2 = DatabaseConnectionManager()
    conn2 = manager2.get_connection()
    
    print(f"Same instance: {manager1 is manager2}")  # True
    print(f"Same connection: {conn1 is conn2}")      # True

3.2 单例模式(Singleton Pattern)

3.2.1 模式定义

单例模式确保一个类只有一个实例,并提供全局访问点。

适用场景: - 数据库连接池 - 日志记录器 - 配置管理器 - 缓存管理器 - 线程池

3.2.2 基础实现

1. 懒汉式(延迟初始化)

// Java实现 - 懒汉式(线程不安全)
public class LazySingleton {
    private static LazySingleton instance;
    
    // 私有构造方法
    private LazySingleton() {
        System.out.println("LazySingleton instance created");
    }
    
    // 公共访问方法
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("LazySingleton doing something...");
    }
}

// 线程安全的懒汉式
public class ThreadSafeLazySingleton {
    private static ThreadSafeLazySingleton instance;
    
    private ThreadSafeLazySingleton() {
        System.out.println("ThreadSafeLazySingleton instance created");
    }
    
    // 同步方法(性能较差)
    public static synchronized ThreadSafeLazySingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeLazySingleton();
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("ThreadSafeLazySingleton doing something...");
    }
}

// 双重检查锁定(推荐)
public class DoubleCheckedLockingSingleton {
    private static volatile DoubleCheckedLockingSingleton instance;
    
    private DoubleCheckedLockingSingleton() {
        System.out.println("DoubleCheckedLockingSingleton instance created");
    }
    
    public static DoubleCheckedLockingSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedLockingSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
    
    public void doSomething() {
        System.out.println("DoubleCheckedLockingSingleton doing something...");
    }
}

2. 饿汉式(立即初始化)

// 饿汉式(线程安全)
public class EagerSingleton {
    // 类加载时就创建实例
    private static final EagerSingleton instance = new EagerSingleton();
    
    private EagerSingleton() {
        System.out.println("EagerSingleton instance created");
    }
    
    public static EagerSingleton getInstance() {
        return instance;
    }
    
    public void doSomething() {
        System.out.println("EagerSingleton doing something...");
    }
}

// 静态内部类(推荐)
public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {
        System.out.println("StaticInnerClassSingleton instance created");
    }
    
    // 静态内部类
    private static class SingletonHolder {
        private static final StaticInnerClassSingleton INSTANCE = 
            new StaticInnerClassSingleton();
    }
    
    public static StaticInnerClassSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    
    public void doSomething() {
        System.out.println("StaticInnerClassSingleton doing something...");
    }
}

3. 枚举实现(最佳实践)

// 枚举单例(推荐,防止反射和序列化攻击)
public enum EnumSingleton {
    INSTANCE;
    
    private String data;
    
    EnumSingleton() {
        System.out.println("EnumSingleton instance created");
        this.data = "Singleton Data";
    }
    
    public void doSomething() {
        System.out.println("EnumSingleton doing something with: " + data);
    }
    
    public String getData() {
        return data;
    }
    
    public void setData(String data) {
        this.data = data;
    }
}

// 使用示例
public class SingletonDemo {
    public static void main(String[] args) {
        // 测试各种单例实现
        System.out.println("=== Lazy Singleton ===");
        LazySingleton lazy1 = LazySingleton.getInstance();
        LazySingleton lazy2 = LazySingleton.getInstance();
        System.out.println("Same instance: " + (lazy1 == lazy2));
        
        System.out.println("\n=== Eager Singleton ===");
        EagerSingleton eager1 = EagerSingleton.getInstance();
        EagerSingleton eager2 = EagerSingleton.getInstance();
        System.out.println("Same instance: " + (eager1 == eager2));
        
        System.out.println("\n=== Static Inner Class Singleton ===");
        StaticInnerClassSingleton static1 = StaticInnerClassSingleton.getInstance();
        StaticInnerClassSingleton static2 = StaticInnerClassSingleton.getInstance();
        System.out.println("Same instance: " + (static1 == static2));
        
        System.out.println("\n=== Enum Singleton ===");
        EnumSingleton enum1 = EnumSingleton.INSTANCE;
        EnumSingleton enum2 = EnumSingleton.INSTANCE;
        System.out.println("Same instance: " + (enum1 == enum2));
        enum1.doSomething();
    }
}

3.2.3 Python实现

import threading
from typing import Optional

# 方法1:使用__new__方法
class SingletonMeta(type):
    """单例元类"""
    _instances = {}
    _lock = threading.Lock()
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            with cls._lock:
                if cls not in cls._instances:
                    cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class DatabaseManager(metaclass=SingletonMeta):
    """数据库管理器单例"""
    
    def __init__(self):
        if hasattr(self, '_initialized'):
            return
        self._initialized = True
        self.connection = None
        self.host = "localhost"
        self.port = 5432
        print("DatabaseManager initialized")
    
    def connect(self):
        if not self.connection:
            self.connection = f"Connected to {self.host}:{self.port}"
            print(f"Database connected: {self.connection}")
        return self.connection
    
    def disconnect(self):
        if self.connection:
            print(f"Database disconnected: {self.connection}")
            self.connection = None
    
    def execute_query(self, query: str):
        if not self.connection:
            self.connect()
        print(f"Executing query: {query}")
        return f"Result of: {query}"

# 方法2:装饰器实现
def singleton(cls):
    """单例装饰器"""
    instances = {}
    lock = threading.Lock()
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            with lock:
                if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance

@singleton
class ConfigManager:
    """配置管理器单例"""
    
    def __init__(self):
        self.config = {
            'debug': True,
            'database_url': 'postgresql://localhost:5432/mydb',
            'cache_timeout': 300,
            'max_connections': 100
        }
        print("ConfigManager initialized")
    
    def get(self, key: str, default=None):
        return self.config.get(key, default)
    
    def set(self, key: str, value):
        self.config[key] = value
        print(f"Config updated: {key} = {value}")
    
    def get_all(self):
        return self.config.copy()

# 方法3:模块级单例(Python推荐方式)
class _LoggerSingleton:
    """日志记录器单例实现"""
    
    def __init__(self):
        self.logs = []
        self.level = "INFO"
        print("Logger initialized")
    
    def log(self, level: str, message: str):
        import datetime
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] {level}: {message}"
        self.logs.append(log_entry)
        print(log_entry)
    
    def info(self, message: str):
        self.log("INFO", message)
    
    def warning(self, message: str):
        self.log("WARNING", message)
    
    def error(self, message: str):
        self.log("ERROR", message)
    
    def get_logs(self):
        return self.logs.copy()
    
    def clear_logs(self):
        self.logs.clear()
        print("Logs cleared")

# 创建模块级单例实例
logger = _LoggerSingleton()

# 方法4:使用__new__的简单实现
class CacheManager:
    """缓存管理器单例"""
    _instance: Optional['CacheManager'] = None
    _lock = threading.Lock()
    
    def __new__(cls):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        if self._initialized:
            return
        self._initialized = True
        self.cache = {}
        self.max_size = 1000
        print("CacheManager initialized")
    
    def get(self, key: str):
        return self.cache.get(key)
    
    def set(self, key: str, value, ttl: int = 3600):
        if len(self.cache) >= self.max_size:
            # 简单的LRU:移除第一个元素
            first_key = next(iter(self.cache))
            del self.cache[first_key]
        
        import time
        self.cache[key] = {
            'value': value,
            'expires': time.time() + ttl
        }
        print(f"Cache set: {key} = {value}")
    
    def delete(self, key: str):
        if key in self.cache:
            del self.cache[key]
            print(f"Cache deleted: {key}")
    
    def clear(self):
        self.cache.clear()
        print("Cache cleared")
    
    def size(self):
        return len(self.cache)

# 使用示例
def test_singletons():
    print("=== Testing Database Manager ===")
    db1 = DatabaseManager()
    db2 = DatabaseManager()
    print(f"Same instance: {db1 is db2}")
    
    db1.connect()
    db2.execute_query("SELECT * FROM users")
    
    print("\n=== Testing Config Manager ===")
    config1 = ConfigManager()
    config2 = ConfigManager()
    print(f"Same instance: {config1 is config2}")
    
    config1.set('debug', False)
    print(f"Debug from config2: {config2.get('debug')}")
    
    print("\n=== Testing Logger ===")
    logger.info("Application started")
    logger.warning("This is a warning")
    logger.error("An error occurred")
    
    print(f"Total logs: {len(logger.get_logs())}")
    
    print("\n=== Testing Cache Manager ===")
    cache1 = CacheManager()
    cache2 = CacheManager()
    print(f"Same instance: {cache1 is cache2}")
    
    cache1.set('user:123', {'name': 'John', 'age': 30})
    user_data = cache2.get('user:123')
    print(f"User data from cache2: {user_data}")
    
    print(f"Cache size: {cache1.size()}")

if __name__ == "__main__":
    test_singletons()

3.2.4 实际应用案例

#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>

// C++实现的应用配置管理器
class ApplicationConfig {
private:
    static std::unique_ptr<ApplicationConfig> instance;
    static std::mutex mutex;
    
    std::unordered_map<std::string, std::string> config;
    
    // 私有构造函数
    ApplicationConfig() {
        loadDefaultConfig();
        std::cout << "ApplicationConfig initialized" << std::endl;
    }
    
    void loadDefaultConfig() {
        config["app_name"] = "MyApplication";
        config["version"] = "1.0.0";
        config["debug"] = "true";
        config["max_threads"] = "10";
        config["timeout"] = "30";
    }
    
public:
    // 删除拷贝构造函数和赋值操作符
    ApplicationConfig(const ApplicationConfig&) = delete;
    ApplicationConfig& operator=(const ApplicationConfig&) = delete;
    
    static ApplicationConfig* getInstance() {
        std::lock_guard<std::mutex> lock(mutex);
        if (instance == nullptr) {
            instance = std::unique_ptr<ApplicationConfig>(new ApplicationConfig());
        }
        return instance.get();
    }
    
    std::string get(const std::string& key, const std::string& defaultValue = "") {
        auto it = config.find(key);
        return (it != config.end()) ? it->second : defaultValue;
    }
    
    void set(const std::string& key, const std::string& value) {
        config[key] = value;
        std::cout << "Config updated: " << key << " = " << value << std::endl;
    }
    
    bool getBool(const std::string& key, bool defaultValue = false) {
        std::string value = get(key);
        if (value == "true" || value == "1") return true;
        if (value == "false" || value == "0") return false;
        return defaultValue;
    }
    
    int getInt(const std::string& key, int defaultValue = 0) {
        try {
            return std::stoi(get(key));
        } catch (...) {
            return defaultValue;
        }
    }
    
    void printAll() {
        std::cout << "Current configuration:" << std::endl;
        for (const auto& pair : config) {
            std::cout << "  " << pair.first << " = " << pair.second << std::endl;
        }
    }
};

// 静态成员定义
std::unique_ptr<ApplicationConfig> ApplicationConfig::instance = nullptr;
std::mutex ApplicationConfig::mutex;

// 线程池单例
class ThreadPool {
private:
    static std::unique_ptr<ThreadPool> instance;
    static std::mutex mutex;
    
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
    
    ThreadPool(size_t numThreads) : stop(false) {
        for (size_t i = 0; i < numThreads; ++i) {
            workers.emplace_back([this] {
                for (;;) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queueMutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        
                        if (this->stop && this->tasks.empty()) {
                            return;
                        }
                        
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
        std::cout << "ThreadPool initialized with " << numThreads << " threads" << std::endl;
    }
    
public:
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    
    static ThreadPool* getInstance() {
        std::lock_guard<std::mutex> lock(mutex);
        if (instance == nullptr) {
            auto config = ApplicationConfig::getInstance();
            size_t numThreads = config->getInt("max_threads", 4);
            instance = std::unique_ptr<ThreadPool>(new ThreadPool(numThreads));
        }
        return instance.get();
    }
    
    template<class F, class... Args>
    auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        using return_type = typename std::result_of<F(Args...)>::type;
        
        auto task = std::make_shared<std::packaged_task<return_type()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        
        std::future<return_type> res = task->get_future();
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            if (stop) {
                throw std::runtime_error("enqueue on stopped ThreadPool");
            }
            tasks.emplace([task]() { (*task)(); });
        }
        condition.notify_one();
        return res;
    }
    
    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread &worker : workers) {
            worker.join();
        }
        std::cout << "ThreadPool destroyed" << std::endl;
    }
};

std::unique_ptr<ThreadPool> ThreadPool::instance = nullptr;
std::mutex ThreadPool::mutex;

// 使用示例
int main() {
    std::cout << "=== Testing ApplicationConfig Singleton ===" << std::endl;
    
    auto config1 = ApplicationConfig::getInstance();
    auto config2 = ApplicationConfig::getInstance();
    
    std::cout << "Same instance: " << (config1 == config2) << std::endl;
    
    config1->printAll();
    
    config1->set("database_url", "postgresql://localhost:5432/mydb");
    std::cout << "Database URL from config2: " << config2->get("database_url") << std::endl;
    
    std::cout << "\n=== Testing ThreadPool Singleton ===" << std::endl;
    
    auto pool1 = ThreadPool::getInstance();
    auto pool2 = ThreadPool::getInstance();
    
    std::cout << "Same instance: " << (pool1 == pool2) << std::endl;
    
    // 提交一些任务
    auto result1 = pool1->enqueue([](int x) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        return x * x;
    }, 5);
    
    auto result2 = pool2->enqueue([](const std::string& msg) {
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        return "Processed: " + msg;
    }, "Hello World");
    
    std::cout << "Result 1: " << result1.get() << std::endl;
    std::cout << "Result 2: " << result2.get() << std::endl;
    
    return 0;
}

3.2.5 单例模式的优缺点

优点: 1. 确保全局只有一个实例 2. 提供全局访问点 3. 延迟初始化,节省资源 4. 避免资源冲突

缺点: 1. 违反单一职责原则 2. 难以进行单元测试 3. 隐藏依赖关系 4. 在多线程环境下需要特殊处理

使用建议: 1. 谨慎使用,避免滥用 2. 考虑依赖注入替代方案 3. 确保线程安全 4. 提供清理机制

3.3 工厂模式(Factory Pattern)

3.3.1 简单工厂模式

简单工厂模式通过一个工厂类来创建不同类型的对象。

// 产品接口
interface Shape {
    void draw();
    double getArea();
}

// 具体产品
class Circle implements Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a Circle with radius: " + radius);
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width, height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle: " + width + " x " + height);
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

class Triangle implements Shape {
    private double base, height;
    
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing a Triangle: base=" + base + ", height=" + height);
    }
    
    @Override
    public double getArea() {
        return 0.5 * base * height;
    }
}

// 简单工厂
class ShapeFactory {
    public static Shape createShape(String type, double... params) {
        if (type == null || type.isEmpty()) {
            throw new IllegalArgumentException("Shape type cannot be null or empty");
        }
        
        switch (type.toLowerCase()) {
            case "circle":
                if (params.length != 1) {
                    throw new IllegalArgumentException("Circle requires 1 parameter: radius");
                }
                return new Circle(params[0]);
                
            case "rectangle":
                if (params.length != 2) {
                    throw new IllegalArgumentException("Rectangle requires 2 parameters: width, height");
                }
                return new Rectangle(params[0], params[1]);
                
            case "triangle":
                if (params.length != 2) {
                    throw new IllegalArgumentException("Triangle requires 2 parameters: base, height");
                }
                return new Triangle(params[0], params[1]);
                
            default:
                throw new IllegalArgumentException("Unknown shape type: " + type);
        }
    }
    
    // 重载方法,提供更友好的接口
    public static Shape createCircle(double radius) {
        return new Circle(radius);
    }
    
    public static Shape createRectangle(double width, double height) {
        return new Rectangle(width, height);
    }
    
    public static Shape createTriangle(double base, double height) {
        return new Triangle(base, height);
    }
}

// 使用示例
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        try {
            // 使用工厂创建不同形状
            Shape circle = ShapeFactory.createShape("circle", 5.0);
            Shape rectangle = ShapeFactory.createShape("rectangle", 4.0, 6.0);
            Shape triangle = ShapeFactory.createShape("triangle", 3.0, 4.0);
            
            // 使用重载方法
            Shape circle2 = ShapeFactory.createCircle(3.0);
            Shape rectangle2 = ShapeFactory.createRectangle(5.0, 8.0);
            
            Shape[] shapes = {circle, rectangle, triangle, circle2, rectangle2};
            
            System.out.println("=== Drawing Shapes ===");
            for (Shape shape : shapes) {
                shape.draw();
                System.out.println("Area: " + shape.getArea());
                System.out.println();
            }
            
        } catch (IllegalArgumentException e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

3.3.2 工厂方法模式

工厂方法模式定义创建对象的接口,让子类决定实例化哪个类。

from abc import ABC, abstractmethod
from typing import List, Dict, Any
import json
import xml.etree.ElementTree as ET

# 产品接口
class Document(ABC):
    """文档抽象基类"""
    
    def __init__(self, title: str):
        self.title = title
        self.content = []
    
    @abstractmethod
    def add_content(self, content: str) -> None:
        pass
    
    @abstractmethod
    def save(self, filename: str) -> None:
        pass
    
    @abstractmethod
    def load(self, filename: str) -> None:
        pass
    
    def get_title(self) -> str:
        return self.title
    
    def get_content(self) -> List[str]:
        return self.content.copy()

# 具体产品
class PDFDocument(Document):
    """PDF文档"""
    
    def __init__(self, title: str):
        super().__init__(title)
        self.format = "PDF"
        self.metadata = {"author": "", "subject": "", "keywords": []}
    
    def add_content(self, content: str) -> None:
        self.content.append(f"[PDF] {content}")
        print(f"Added to PDF: {content}")
    
    def save(self, filename: str) -> None:
        print(f"Saving PDF document '{self.title}' to {filename}.pdf")
        # 模拟PDF保存逻辑
        with open(f"{filename}.pdf.txt", 'w') as f:
            f.write(f"PDF Document: {self.title}\n")
            f.write(f"Format: {self.format}\n")
            f.write(f"Metadata: {self.metadata}\n")
            for item in self.content:
                f.write(f"{item}\n")
    
    def load(self, filename: str) -> None:
        print(f"Loading PDF document from {filename}.pdf")
        # 模拟PDF加载逻辑
    
    def set_metadata(self, author: str, subject: str, keywords: List[str]):
        self.metadata.update({
            "author": author,
            "subject": subject,
            "keywords": keywords
        })

class WordDocument(Document):
    """Word文档"""
    
    def __init__(self, title: str):
        super().__init__(title)
        self.format = "DOCX"
        self.styles = []
    
    def add_content(self, content: str) -> None:
        self.content.append(f"[WORD] {content}")
        print(f"Added to Word: {content}")
    
    def save(self, filename: str) -> None:
        print(f"Saving Word document '{self.title}' to {filename}.docx")
        # 模拟Word保存逻辑
        with open(f"{filename}.docx.txt", 'w') as f:
            f.write(f"Word Document: {self.title}\n")
            f.write(f"Format: {self.format}\n")
            f.write(f"Styles: {self.styles}\n")
            for item in self.content:
                f.write(f"{item}\n")
    
    def load(self, filename: str) -> None:
        print(f"Loading Word document from {filename}.docx")
        # 模拟Word加载逻辑
    
    def add_style(self, style: str):
        self.styles.append(style)
        print(f"Added style: {style}")

class HTMLDocument(Document):
    """HTML文档"""
    
    def __init__(self, title: str):
        super().__init__(title)
        self.format = "HTML"
        self.css_classes = []
    
    def add_content(self, content: str) -> None:
        self.content.append(f"<p>{content}</p>")
        print(f"Added to HTML: {content}")
    
    def save(self, filename: str) -> None:
        print(f"Saving HTML document '{self.title}' to {filename}.html")
        with open(f"{filename}.html", 'w') as f:
            f.write(f"<!DOCTYPE html>\n")
            f.write(f"<html>\n<head>\n<title>{self.title}</title>\n</head>\n<body>\n")
            for item in self.content:
                f.write(f"{item}\n")
            f.write("</body>\n</html>")
    
    def load(self, filename: str) -> None:
        print(f"Loading HTML document from {filename}.html")
        # 模拟HTML加载逻辑
    
    def add_css_class(self, css_class: str):
        self.css_classes.append(css_class)
        print(f"Added CSS class: {css_class}")

# 抽象工厂
class DocumentFactory(ABC):
    """文档工厂抽象基类"""
    
    @abstractmethod
    def create_document(self, title: str) -> Document:
        pass
    
    def process_document(self, title: str, contents: List[str]) -> Document:
        """模板方法:创建并处理文档"""
        doc = self.create_document(title)
        for content in contents:
            doc.add_content(content)
        return doc

# 具体工厂
class PDFDocumentFactory(DocumentFactory):
    """PDF文档工厂"""
    
    def create_document(self, title: str) -> PDFDocument:
        print(f"Creating PDF document: {title}")
        return PDFDocument(title)

class WordDocumentFactory(DocumentFactory):
    """Word文档工厂"""
    
    def create_document(self, title: str) -> WordDocument:
        print(f"Creating Word document: {title}")
        return WordDocument(title)

class HTMLDocumentFactory(DocumentFactory):
    """HTML文档工厂"""
    
    def create_document(self, title: str) -> HTMLDocument:
        print(f"Creating HTML document: {title}")
        return HTMLDocument(title)

# 工厂注册器
class DocumentFactoryRegistry:
    """工厂注册器,支持动态注册新的工厂"""
    
    def __init__(self):
        self._factories: Dict[str, DocumentFactory] = {}
        self._register_default_factories()
    
    def _register_default_factories(self):
        """注册默认工厂"""
        self.register("pdf", PDFDocumentFactory())
        self.register("word", WordDocumentFactory())
        self.register("html", HTMLDocumentFactory())
    
    def register(self, doc_type: str, factory: DocumentFactory):
        """注册工厂"""
        self._factories[doc_type.lower()] = factory
        print(f"Registered factory for type: {doc_type}")
    
    def create_document(self, doc_type: str, title: str) -> Document:
        """创建文档"""
        factory = self._factories.get(doc_type.lower())
        if not factory:
            raise ValueError(f"No factory registered for document type: {doc_type}")
        return factory.create_document(title)
    
    def get_supported_types(self) -> List[str]:
        """获取支持的文档类型"""
        return list(self._factories.keys())

# 使用示例
def test_factory_method():
    print("=== Factory Method Pattern Demo ===")
    
    # 创建工厂注册器
    registry = DocumentFactoryRegistry()
    
    print(f"Supported document types: {registry.get_supported_types()}")
    print()
    
    # 创建不同类型的文档
    documents = []
    
    # PDF文档
    pdf_doc = registry.create_document("pdf", "Annual Report 2024")
    pdf_doc.add_content("Executive Summary")
    pdf_doc.add_content("Financial Overview")
    pdf_doc.add_content("Future Outlook")
    if isinstance(pdf_doc, PDFDocument):
        pdf_doc.set_metadata("John Doe", "Annual Report", ["finance", "report", "2024"])
    documents.append(pdf_doc)
    
    print()
    
    # Word文档
    word_doc = registry.create_document("word", "Project Proposal")
    word_doc.add_content("Project Overview")
    word_doc.add_content("Timeline and Milestones")
    word_doc.add_content("Budget Estimation")
    if isinstance(word_doc, WordDocument):
        word_doc.add_style("Heading 1")
        word_doc.add_style("Normal")
    documents.append(word_doc)
    
    print()
    
    # HTML文档
    html_doc = registry.create_document("html", "Company Website")
    html_doc.add_content("Welcome to our company!")
    html_doc.add_content("We provide excellent services.")
    html_doc.add_content("Contact us for more information.")
    if isinstance(html_doc, HTMLDocument):
        html_doc.add_css_class("header")
        html_doc.add_css_class("content")
    documents.append(html_doc)
    
    print()
    
    # 保存所有文档
    print("=== Saving Documents ===")
    for i, doc in enumerate(documents):
        doc.save(f"document_{i+1}")
    
    print()
    
    # 使用工厂的模板方法
    print("=== Using Factory Template Method ===")
    pdf_factory = PDFDocumentFactory()
    quick_doc = pdf_factory.process_document(
        "Quick Guide",
        ["Step 1: Install software", "Step 2: Configure settings", "Step 3: Start using"]
    )
    quick_doc.save("quick_guide")

if __name__ == "__main__":
    test_factory_method()

3.3.3 抽象工厂模式

抽象工厂模式提供创建相关对象家族的接口。

#include <iostream>
#include <memory>
#include <string>
#include <vector>

// 抽象产品A:按钮
class Button {
public:
    virtual ~Button() = default;
    virtual void render() = 0;
    virtual void onClick() = 0;
};

// 抽象产品B:文本框
class TextBox {
public:
    virtual ~TextBox() = default;
    virtual void render() = 0;
    virtual void setText(const std::string& text) = 0;
    virtual std::string getText() = 0;
};

// 抽象产品C:复选框
class CheckBox {
public:
    virtual ~CheckBox() = default;
    virtual void render() = 0;
    virtual void setChecked(bool checked) = 0;
    virtual bool isChecked() = 0;
};

// Windows风格的具体产品
class WindowsButton : public Button {
public:
    void render() override {
        std::cout << "Rendering Windows-style button" << std::endl;
    }
    
    void onClick() override {
        std::cout << "Windows button clicked!" << std::endl;
    }
};

class WindowsTextBox : public TextBox {
private:
    std::string text;
    
public:
    void render() override {
        std::cout << "Rendering Windows-style text box" << std::endl;
    }
    
    void setText(const std::string& text) override {
        this->text = text;
        std::cout << "Windows text box text set to: " << text << std::endl;
    }
    
    std::string getText() override {
        return text;
    }
};

class WindowsCheckBox : public CheckBox {
private:
    bool checked = false;
    
public:
    void render() override {
        std::cout << "Rendering Windows-style checkbox" << std::endl;
    }
    
    void setChecked(bool checked) override {
        this->checked = checked;
        std::cout << "Windows checkbox " << (checked ? "checked" : "unchecked") << std::endl;
    }
    
    bool isChecked() override {
        return checked;
    }
};

// macOS风格的具体产品
class MacButton : public Button {
public:
    void render() override {
        std::cout << "Rendering macOS-style button" << std::endl;
    }
    
    void onClick() override {
        std::cout << "macOS button clicked!" << std::endl;
    }
};

class MacTextBox : public TextBox {
private:
    std::string text;
    
public:
    void render() override {
        std::cout << "Rendering macOS-style text box" << std::endl;
    }
    
    void setText(const std::string& text) override {
        this->text = text;
        std::cout << "macOS text box text set to: " << text << std::endl;
    }
    
    std::string getText() override {
        return text;
    }
};

class MacCheckBox : public CheckBox {
private:
    bool checked = false;
    
public:
    void render() override {
        std::cout << "Rendering macOS-style checkbox" << std::endl;
    }
    
    void setChecked(bool checked) override {
        this->checked = checked;
        std::cout << "macOS checkbox " << (checked ? "checked" : "unchecked") << std::endl;
    }
    
    bool isChecked() override {
        return checked;
    }
};

// Linux风格的具体产品
class LinuxButton : public Button {
public:
    void render() override {
        std::cout << "Rendering Linux-style button" << std::endl;
    }
    
    void onClick() override {
        std::cout << "Linux button clicked!" << std::endl;
    }
};

class LinuxTextBox : public TextBox {
private:
    std::string text;
    
public:
    void render() override {
        std::cout << "Rendering Linux-style text box" << std::endl;
    }
    
    void setText(const std::string& text) override {
        this->text = text;
        std::cout << "Linux text box text set to: " << text << std::endl;
    }
    
    std::string getText() override {
        return text;
    }
};

class LinuxCheckBox : public CheckBox {
private:
    bool checked = false;
    
public:
    void render() override {
        std::cout << "Rendering Linux-style checkbox" << std::endl;
    }
    
    void setChecked(bool checked) override {
        this->checked = checked;
        std::cout << "Linux checkbox " << (checked ? "checked" : "unchecked") << std::endl;
    }
    
    bool isChecked() override {
        return checked;
    }
};

// 抽象工厂
class GUIFactory {
public:
    virtual ~GUIFactory() = default;
    virtual std::unique_ptr<Button> createButton() = 0;
    virtual std::unique_ptr<TextBox> createTextBox() = 0;
    virtual std::unique_ptr<CheckBox> createCheckBox() = 0;
    virtual std::string getTheme() = 0;
};

// 具体工厂
class WindowsFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<WindowsButton>();
    }
    
    std::unique_ptr<TextBox> createTextBox() override {
        return std::make_unique<WindowsTextBox>();
    }
    
    std::unique_ptr<CheckBox> createCheckBox() override {
        return std::make_unique<WindowsCheckBox>();
    }
    
    std::string getTheme() override {
        return "Windows";
    }
};

class MacFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<MacButton>();
    }
    
    std::unique_ptr<TextBox> createTextBox() override {
        return std::make_unique<MacTextBox>();
    }
    
    std::unique_ptr<CheckBox> createCheckBox() override {
        return std::make_unique<MacCheckBox>();
    }
    
    std::string getTheme() override {
        return "macOS";
    }
};

class LinuxFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<LinuxButton>();
    }
    
    std::unique_ptr<TextBox> createTextBox() override {
        return std::make_unique<LinuxTextBox>();
    }
    
    std::unique_ptr<CheckBox> createCheckBox() override {
        return std::make_unique<LinuxCheckBox>();
    }
    
    std::string getTheme() override {
        return "Linux";
    }
};

// 客户端应用程序
class Application {
private:
    std::unique_ptr<GUIFactory> factory;
    std::unique_ptr<Button> button;
    std::unique_ptr<TextBox> textBox;
    std::unique_ptr<CheckBox> checkBox;
    
public:
    Application(std::unique_ptr<GUIFactory> factory) : factory(std::move(factory)) {
        createUI();
    }
    
    void createUI() {
        std::cout << "Creating UI with " << factory->getTheme() << " theme" << std::endl;
        
        button = factory->createButton();
        textBox = factory->createTextBox();
        checkBox = factory->createCheckBox();
        
        std::cout << "UI components created successfully" << std::endl;
    }
    
    void renderUI() {
        std::cout << "\n=== Rendering UI ===" << std::endl;
        button->render();
        textBox->render();
        checkBox->render();
    }
    
    void interactWithUI() {
        std::cout << "\n=== Interacting with UI ===" << std::endl;
        
        button->onClick();
        
        textBox->setText("Hello, " + factory->getTheme() + "!");
        std::cout << "Text box content: " << textBox->getText() << std::endl;
        
        checkBox->setChecked(true);
        std::cout << "Checkbox state: " << (checkBox->isChecked() ? "checked" : "unchecked") << std::endl;
    }
};

// 工厂选择器
class FactorySelector {
public:
    static std::unique_ptr<GUIFactory> createFactory(const std::string& platform) {
        if (platform == "windows") {
            return std::make_unique<WindowsFactory>();
        } else if (platform == "macos") {
            return std::make_unique<MacFactory>();
        } else if (platform == "linux") {
            return std::make_unique<LinuxFactory>();
        } else {
            throw std::invalid_argument("Unsupported platform: " + platform);
        }
    }
    
    static std::vector<std::string> getSupportedPlatforms() {
        return {"windows", "macos", "linux"};
    }
};

// 使用示例
int main() {
    std::cout << "=== Abstract Factory Pattern Demo ===" << std::endl;
    
    auto platforms = FactorySelector::getSupportedPlatforms();
    
    for (const auto& platform : platforms) {
        std::cout << "\n" << std::string(50, '=') << std::endl;
        std::cout << "Testing " << platform << " platform" << std::endl;
        std::cout << std::string(50, '=') << std::endl;
        
        try {
            auto factory = FactorySelector::createFactory(platform);
            Application app(std::move(factory));
            
            app.renderUI();
            app.interactWithUI();
            
        } catch (const std::exception& e) {
            std::cerr << "Error: " << e.what() << std::endl;
        }
    }
    
    // 测试不支持的平台
    std::cout << "\n=== Testing Unsupported Platform ===" << std::endl;
    try {
        auto factory = FactorySelector::createFactory("android");
    } catch (const std::exception& e) {
        std::cerr << "Expected error: " << e.what() << std::endl;
    }
    
    return 0;
}

3.4 本章小结

3.4.1 创建型模式对比

模式 目的 适用场景 优点 缺点
单例 确保唯一实例 全局资源管理 节省资源,全局访问 难以测试,隐藏依赖
简单工厂 集中创建对象 对象类型较少且稳定 简单易用 违反开闭原则
工厂方法 延迟对象创建决策 需要扩展产品类型 符合开闭原则 增加类的数量
抽象工厂 创建产品家族 多个相关产品 保证产品一致性 扩展困难

3.4.2 选择指南

  1. 需要全局唯一实例 → 单例模式
  2. 简单的对象创建 → 简单工厂
  3. 需要扩展产品类型 → 工厂方法
  4. 创建相关产品家族 → 抽象工厂

下一章预告:第04章将学习建造者模式和原型模式,掌握复杂对象的构建和克隆技术。