本章目标
- 理解创建型设计模式的核心思想
- 掌握单例模式的多种实现方式
- 学会使用工厂模式创建对象
- 理解建造者模式的应用场景
- 掌握原型模式的克隆机制
- 学会在实际项目中选择合适的创建型模式
3.1 创建型模式概述
3.1.1 什么是创建型模式
创建型设计模式关注对象的创建过程,它们提供了创建对象的机制,能够提升已有代码的灵活性和可复用性。
核心思想: - 将对象的创建与使用分离 - 隐藏对象创建的复杂性 - 提供灵活的对象创建方式 - 支持对象创建的扩展和变化
3.1.2 创建型模式的分类
- 单例模式(Singleton):确保一个类只有一个实例
- 工厂方法模式(Factory Method):创建对象的接口,让子类决定实例化哪个类
- 抽象工厂模式(Abstract Factory):创建相关对象家族的接口
- 建造者模式(Builder):分步骤构建复杂对象
- 原型模式(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 选择指南
- 需要全局唯一实例 → 单例模式
- 简单的对象创建 → 简单工厂
- 需要扩展产品类型 → 工厂方法
- 创建相关产品家族 → 抽象工厂
下一章预告:第04章将学习建造者模式和原型模式,掌握复杂对象的构建和克隆技术。