chore: import zh skill code-mentor
This commit is contained in:
@@ -0,0 +1,580 @@
|
||||
# 创建型设计模式
|
||||
|
||||
创建型模式处理对象的创建机制,试图以适合当前情境的方式创建对象。
|
||||
|
||||
---
|
||||
|
||||
## 1. 单例模式(Singleton Pattern)
|
||||
|
||||
### 问题
|
||||
你需要一个类的唯一实例(例如,数据库连接、配置管理器、日志记录器)。
|
||||
|
||||
### 反面示例
|
||||
```python
|
||||
# 可以创建多个实例
|
||||
class DatabaseConnection:
|
||||
def __init__(self):
|
||||
self.connection = self.connect()
|
||||
|
||||
def connect(self):
|
||||
print("Connecting to database...")
|
||||
return "DB Connection"
|
||||
|
||||
# 问题:创建了多个连接
|
||||
db1 = DatabaseConnection()
|
||||
db2 = DatabaseConnection()
|
||||
print(db1 is db2) # False — 不同的实例!
|
||||
```
|
||||
|
||||
### 解决方案
|
||||
```python
|
||||
class Singleton:
|
||||
_instance = None
|
||||
|
||||
def __new__(cls):
|
||||
if cls._instance is None:
|
||||
cls._instance = super().__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
class DatabaseConnection(Singleton):
|
||||
def __init__(self):
|
||||
if not hasattr(self, 'initialized'):
|
||||
self.connection = self.connect()
|
||||
self.initialized = True
|
||||
|
||||
def connect(self):
|
||||
print("Connecting to database...")
|
||||
return "DB Connection"
|
||||
|
||||
# 使用示例
|
||||
db1 = DatabaseConnection()
|
||||
db2 = DatabaseConnection()
|
||||
print(db1 is db2) # True — 同一个实例!
|
||||
```
|
||||
|
||||
### JavaScript 实现
|
||||
```javascript
|
||||
class DatabaseConnection {
|
||||
constructor() {
|
||||
if (DatabaseConnection.instance) {
|
||||
return DatabaseConnection.instance;
|
||||
}
|
||||
|
||||
this.connection = this.connect();
|
||||
DatabaseConnection.instance = this;
|
||||
}
|
||||
|
||||
connect() {
|
||||
console.log("Connecting to database...");
|
||||
return "DB Connection";
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const db1 = new DatabaseConnection();
|
||||
const db2 = new DatabaseConnection();
|
||||
console.log(db1 === db2); // true
|
||||
```
|
||||
|
||||
### 何时使用
|
||||
- **适用**:日志记录器、配置管理、连接池、缓存
|
||||
- **不适用**:当你需要多个实例时,或用于简单工具类(改用模块)
|
||||
|
||||
### 优缺点
|
||||
✅ 对唯一实例的受控访问
|
||||
✅ 延迟初始化(Lazy initialization)
|
||||
❌ 全局状态(可能增加测试难度)
|
||||
❌ 可能违反单一职责原则(Single Responsibility Principle)
|
||||
|
||||
---
|
||||
|
||||
## 2. 工厂模式(Factory Pattern)
|
||||
|
||||
### 问题
|
||||
你需要在未指定具体类的情况下创建对象。创建逻辑复杂或依赖于条件。
|
||||
|
||||
### 反面示例
|
||||
```python
|
||||
# 客户端代码需要了解所有具体类
|
||||
class Dog:
|
||||
def speak(self):
|
||||
return "Woof!"
|
||||
|
||||
class Cat:
|
||||
def speak(self):
|
||||
return "Meow!"
|
||||
|
||||
# 客户端必须知道实例化哪个类
|
||||
def get_pet(pet_type):
|
||||
if pet_type == "dog":
|
||||
return Dog()
|
||||
elif pet_type == "cat":
|
||||
return Cat()
|
||||
# 添加新宠物类型需要修改此函数!
|
||||
```
|
||||
|
||||
### 解决方案
|
||||
```python
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
# 抽象产品
|
||||
class Animal(ABC):
|
||||
@abstractmethod
|
||||
def speak(self):
|
||||
pass
|
||||
|
||||
# 具体产品
|
||||
class Dog(Animal):
|
||||
def speak(self):
|
||||
return "Woof!"
|
||||
|
||||
class Cat(Animal):
|
||||
def speak(self):
|
||||
return "Meow!"
|
||||
|
||||
class Bird(Animal):
|
||||
def speak(self):
|
||||
return "Tweet!"
|
||||
|
||||
# 工厂
|
||||
class AnimalFactory:
|
||||
@staticmethod
|
||||
def create_animal(animal_type):
|
||||
animals = {
|
||||
'dog': Dog,
|
||||
'cat': Cat,
|
||||
'bird': Bird
|
||||
}
|
||||
|
||||
animal_class = animals.get(animal_type.lower())
|
||||
if animal_class:
|
||||
return animal_class()
|
||||
raise ValueError(f"Unknown animal type: {animal_type}")
|
||||
|
||||
# 使用示例
|
||||
factory = AnimalFactory()
|
||||
pet = factory.create_animal('dog')
|
||||
print(pet.speak()) # Woof!
|
||||
```
|
||||
|
||||
### JavaScript 实现
|
||||
```javascript
|
||||
class Animal {
|
||||
speak() {
|
||||
throw new Error("Method must be implemented");
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Animal {
|
||||
speak() {
|
||||
return "Woof!";
|
||||
}
|
||||
}
|
||||
|
||||
class Cat extends Animal {
|
||||
speak() {
|
||||
return "Meow!";
|
||||
}
|
||||
}
|
||||
|
||||
class AnimalFactory {
|
||||
static createAnimal(animalType) {
|
||||
const animals = {
|
||||
dog: Dog,
|
||||
cat: Cat
|
||||
};
|
||||
|
||||
const AnimalClass = animals[animalType.toLowerCase()];
|
||||
if (AnimalClass) {
|
||||
return new AnimalClass();
|
||||
}
|
||||
throw new Error(`Unknown animal type: ${animalType}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const pet = AnimalFactory.createAnimal('dog');
|
||||
console.log(pet.speak()); // Woof!
|
||||
```
|
||||
|
||||
### 何时使用
|
||||
- **适用**:当你事先不知道确切类型时,或创建逻辑较为复杂
|
||||
- **不适用**:用于没有变化的简单对象创建
|
||||
|
||||
### 优缺点
|
||||
✅ 客户端与产品之间的松耦合
|
||||
✅ 易于添加新产品(开闭原则,Open/Closed Principle)
|
||||
✅ 集中化的创建逻辑
|
||||
❌ 可能引入大量类
|
||||
|
||||
---
|
||||
|
||||
## 3. 抽象工厂模式(Abstract Factory Pattern)
|
||||
|
||||
### 问题
|
||||
你需要在未指定具体类的情况下创建一组相关的对象家族。
|
||||
|
||||
### 示例:UI 主题工厂
|
||||
|
||||
```python
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
# 抽象产品
|
||||
class Button(ABC):
|
||||
@abstractmethod
|
||||
def render(self):
|
||||
pass
|
||||
|
||||
class Checkbox(ABC):
|
||||
@abstractmethod
|
||||
def render(self):
|
||||
pass
|
||||
|
||||
# 具体产品 —— 浅色主题
|
||||
class LightButton(Button):
|
||||
def render(self):
|
||||
return "Rendering light button"
|
||||
|
||||
class LightCheckbox(Checkbox):
|
||||
def render(self):
|
||||
return "Rendering light checkbox"
|
||||
|
||||
# 具体产品 —— 深色主题
|
||||
class DarkButton(Button):
|
||||
def render(self):
|
||||
return "Rendering dark button"
|
||||
|
||||
class DarkCheckbox(Checkbox):
|
||||
def render(self):
|
||||
return "Rendering dark checkbox"
|
||||
|
||||
# 抽象工厂
|
||||
class UIFactory(ABC):
|
||||
@abstractmethod
|
||||
def create_button(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def create_checkbox(self):
|
||||
pass
|
||||
|
||||
# 具体工厂
|
||||
class LightThemeFactory(UIFactory):
|
||||
def create_button(self):
|
||||
return LightButton()
|
||||
|
||||
def create_checkbox(self):
|
||||
return LightCheckbox()
|
||||
|
||||
class DarkThemeFactory(UIFactory):
|
||||
def create_button(self):
|
||||
return DarkButton()
|
||||
|
||||
def create_checkbox(self):
|
||||
return DarkCheckbox()
|
||||
|
||||
# 客户端代码
|
||||
def create_ui(factory: UIFactory):
|
||||
button = factory.create_button()
|
||||
checkbox = factory.create_checkbox()
|
||||
return button.render(), checkbox.render()
|
||||
|
||||
# 使用示例
|
||||
light_factory = LightThemeFactory()
|
||||
print(create_ui(light_factory))
|
||||
|
||||
dark_factory = DarkThemeFactory()
|
||||
print(create_ui(dark_factory))
|
||||
```
|
||||
|
||||
### 何时使用
|
||||
- **适用**:当你需要一组相关的对象协同工作时
|
||||
- **不适用**:当你只有一个产品家族时
|
||||
|
||||
---
|
||||
|
||||
## 4. 构建器模式(Builder Pattern)
|
||||
|
||||
### 问题
|
||||
你需要逐步构建复杂对象。构造函数参数过多。
|
||||
|
||||
### 反面示例
|
||||
```python
|
||||
# 构造函数参数过多
|
||||
class Pizza:
|
||||
def __init__(self, size, cheese=False, pepperoni=False,
|
||||
mushrooms=False, onions=False, bacon=False,
|
||||
ham=False, pineapple=False):
|
||||
self.size = size
|
||||
self.cheese = cheese
|
||||
self.pepperoni = pepperoni
|
||||
# ... 大量参数
|
||||
|
||||
# 难以阅读,容易出错
|
||||
pizza = Pizza(12, True, True, False, True, False, True, False)
|
||||
```
|
||||
|
||||
### 解决方案
|
||||
```python
|
||||
class Pizza:
|
||||
def __init__(self, size):
|
||||
self.size = size
|
||||
self.cheese = False
|
||||
self.pepperoni = False
|
||||
self.mushrooms = False
|
||||
self.onions = False
|
||||
self.bacon = False
|
||||
|
||||
def __str__(self):
|
||||
toppings = []
|
||||
if self.cheese:
|
||||
toppings.append("cheese")
|
||||
if self.pepperoni:
|
||||
toppings.append("pepperoni")
|
||||
if self.mushrooms:
|
||||
toppings.append("mushrooms")
|
||||
if self.onions:
|
||||
toppings.append("onions")
|
||||
if self.bacon:
|
||||
toppings.append("bacon")
|
||||
|
||||
return f"{self.size}\" pizza with {', '.join(toppings)}"
|
||||
|
||||
class PizzaBuilder:
|
||||
def __init__(self, size):
|
||||
self.pizza = Pizza(size)
|
||||
|
||||
def add_cheese(self):
|
||||
self.pizza.cheese = True
|
||||
return self
|
||||
|
||||
def add_pepperoni(self):
|
||||
self.pizza.pepperoni = True
|
||||
return self
|
||||
|
||||
def add_mushrooms(self):
|
||||
self.pizza.mushrooms = True
|
||||
return self
|
||||
|
||||
def add_onions(self):
|
||||
self.pizza.onions = True
|
||||
return self
|
||||
|
||||
def add_bacon(self):
|
||||
self.pizza.bacon = True
|
||||
return self
|
||||
|
||||
def build(self):
|
||||
return self.pizza
|
||||
|
||||
# 使用示例 —— 可读性大大提升!
|
||||
pizza = (PizzaBuilder(12)
|
||||
.add_cheese()
|
||||
.add_pepperoni()
|
||||
.add_mushrooms()
|
||||
.build())
|
||||
|
||||
print(pizza) # 12" pizza with cheese, pepperoni, mushrooms
|
||||
```
|
||||
|
||||
### JavaScript 实现
|
||||
```javascript
|
||||
class Pizza {
|
||||
constructor(size) {
|
||||
this.size = size;
|
||||
this.toppings = [];
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.size}" pizza with ${this.toppings.join(', ')}`;
|
||||
}
|
||||
}
|
||||
|
||||
class PizzaBuilder {
|
||||
constructor(size) {
|
||||
this.pizza = new Pizza(size);
|
||||
}
|
||||
|
||||
addCheese() {
|
||||
this.pizza.toppings.push('cheese');
|
||||
return this;
|
||||
}
|
||||
|
||||
addPepperoni() {
|
||||
this.pizza.toppings.push('pepperoni');
|
||||
return this;
|
||||
}
|
||||
|
||||
addMushrooms() {
|
||||
this.pizza.toppings.push('mushrooms');
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return this.pizza;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const pizza = new PizzaBuilder(12)
|
||||
.addCheese()
|
||||
.addPepperoni()
|
||||
.addMushrooms()
|
||||
.build();
|
||||
|
||||
console.log(pizza.toString());
|
||||
```
|
||||
|
||||
### 何时使用
|
||||
- **适用**:构造函数参数多、需要逐步构建、需要不可变对象
|
||||
- **不适用**:参数少的简单对象
|
||||
|
||||
### 优缺点
|
||||
✅ 可读性强的流畅接口(Fluent Interface)
|
||||
✅ 对构建过程的精细控制
|
||||
✅ 可以创建不同的表示形式
|
||||
❌ 代码量增加(需要构建器类)
|
||||
|
||||
---
|
||||
|
||||
## 5. 原型模式(Prototype Pattern)
|
||||
|
||||
### 问题
|
||||
你需要复制现有对象,而不让代码依赖于它们的类。
|
||||
|
||||
### 解决方案
|
||||
```python
|
||||
import copy
|
||||
|
||||
class Prototype:
|
||||
def clone(self):
|
||||
"""对象的深拷贝。"""
|
||||
return copy.deepcopy(self)
|
||||
|
||||
class Shape(Prototype):
|
||||
def __init__(self, shape_type, color):
|
||||
self.shape_type = shape_type
|
||||
self.color = color
|
||||
self.coordinates = []
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.color} {self.shape_type} at {self.coordinates}"
|
||||
|
||||
# 使用示例
|
||||
original = Shape("Circle", "Red")
|
||||
original.coordinates = [10, 20]
|
||||
|
||||
# 克隆
|
||||
clone = original.clone()
|
||||
clone.color = "Blue"
|
||||
clone.coordinates = [30, 40]
|
||||
|
||||
print(original) # Red Circle at [10, 20]
|
||||
print(clone) # Blue Circle at [30, 40]
|
||||
```
|
||||
|
||||
### JavaScript 实现
|
||||
```javascript
|
||||
class Shape {
|
||||
constructor(shapeType, color) {
|
||||
this.shapeType = shapeType;
|
||||
this.color = color;
|
||||
this.coordinates = [];
|
||||
}
|
||||
|
||||
clone() {
|
||||
const cloned = Object.create(Object.getPrototypeOf(this));
|
||||
cloned.shapeType = this.shapeType;
|
||||
cloned.color = this.color;
|
||||
cloned.coordinates = [...this.coordinates];
|
||||
return cloned;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `${this.color} ${this.shapeType} at ${this.coordinates}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
const original = new Shape("Circle", "Red");
|
||||
original.coordinates = [10, 20];
|
||||
|
||||
const clone = original.clone();
|
||||
clone.color = "Blue";
|
||||
clone.coordinates = [30, 40];
|
||||
|
||||
console.log(original.toString()); // Red Circle at 10,20
|
||||
console.log(clone.toString()); // Blue Circle at 30,40
|
||||
```
|
||||
|
||||
### 何时使用
|
||||
- **适用**:对象创建成本高,需要大量相似对象
|
||||
- **不适用**:简单对象,浅拷贝即可满足需求
|
||||
|
||||
---
|
||||
|
||||
## 模式选择指南
|
||||
|
||||
| 模式 | 适用场景 | 典型用例 |
|
||||
|---------|----------|-------------------|
|
||||
| **单例模式(Singleton)** | 需要唯一实例 | 日志记录器、配置管理、数据库连接池 |
|
||||
| **工厂模式(Factory)** | 编译时不知道具体类 | 插件系统、文档类型 |
|
||||
| **抽象工厂模式(Abstract Factory)** | 需要一组相关的对象 | UI 主题、跨平台应用 |
|
||||
| **构建器模式(Builder)** | 参数众多的复杂构建过程 | 查询构建器、文档构建器 |
|
||||
| **原型模式(Prototype)** | 创建成本高,需要副本 | 游戏实体、图形编辑器 |
|
||||
|
||||
---
|
||||
|
||||
## 应避免的反模式
|
||||
|
||||
### 1. 过度使用单例
|
||||
```python
|
||||
# 不要把所有东西都做成单例
|
||||
class MathUtils(Singleton): # 糟糕 —— 直接使用模块即可!
|
||||
@staticmethod
|
||||
def add(a, b):
|
||||
return a + b
|
||||
|
||||
# 应使用模块级函数
|
||||
def add(a, b):
|
||||
return a + b
|
||||
```
|
||||
|
||||
### 2. 上帝工厂
|
||||
```python
|
||||
# 不要用一个工厂处理所有事情
|
||||
class GodFactory:
|
||||
def create_user(self): ...
|
||||
def create_product(self): ...
|
||||
def create_order(self): ...
|
||||
# ... 还有 50 多个方法
|
||||
|
||||
# 应按不同关注点使用独立的工厂
|
||||
class UserFactory: ...
|
||||
class ProductFactory: ...
|
||||
class OrderFactory: ...
|
||||
```
|
||||
|
||||
### 3. 过早抽象
|
||||
```python
|
||||
# 不要在简单情况下创建工厂
|
||||
class DogFactory:
|
||||
@staticmethod
|
||||
def create():
|
||||
return Dog() # 只有一个简单的类
|
||||
|
||||
# 应直接实例化
|
||||
dog = Dog()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键要点
|
||||
|
||||
1. **单例模式**:唯一实例,全局访问
|
||||
2. **工厂模式**:将对象创建与使用解耦
|
||||
3. **抽象工厂模式**:一组相关的对象家族
|
||||
4. **构建器模式**:逐步构建复杂对象
|
||||
5. **原型模式**:克隆现有对象
|
||||
|
||||
**请记住**:在模式确实能解决实际问题时再使用。不要在模式不适用时强行套用!
|
||||
Reference in New Issue
Block a user