本章目标
- 理解设计模式的定义和重要性
- 掌握面向对象设计的基本原则
- 了解设计模式的分类和特点
- 学会如何选择和应用设计模式
1.1 什么是设计模式
1.1.1 设计模式的定义
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计中某些经常出现的问题,以及该问题的解决方案。
Christopher Alexander的定义: > “每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动。”
GoF的定义: > “设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。”
1.1.2 设计模式的组成要素
每个设计模式都包含以下四个基本要素:
模式名称(Pattern Name)
- 用一个词或短语来描述模式
- 便于交流和记忆
- 提高设计词汇量
问题(Problem)
- 描述何时使用该模式
- 解释设计问题和问题存在的前因后果
- 可能描述特定的设计问题
解决方案(Solution)
- 描述设计的组成成分
- 它们之间的相互关系
- 各自的职责和协作方式
效果(Consequences)
- 描述模式应用的效果
- 以及使用模式应权衡的问题
- 包括对系统的灵活性、扩充性或可移植性的影响
1.1.3 设计模式的优点
# 示例:不使用设计模式的代码
class OrderProcessor:
def process_order(self, order_type, order_data):
if order_type == "online":
# 在线订单处理逻辑
print("Processing online order")
# 验证支付信息
# 检查库存
# 发送确认邮件
elif order_type == "phone":
# 电话订单处理逻辑
print("Processing phone order")
# 记录通话信息
# 人工验证
# 发送短信确认
elif order_type == "store":
# 店内订单处理逻辑
print("Processing store order")
# 打印收据
# 更新库存
# 如果需要添加新的订单类型,需要修改这个方法
# 使用策略模式重构后的代码
from abc import ABC, abstractmethod
class OrderProcessingStrategy(ABC):
@abstractmethod
def process(self, order_data):
pass
class OnlineOrderStrategy(OrderProcessingStrategy):
def process(self, order_data):
print("Processing online order")
# 在线订单特定逻辑
return "Online order processed"
class PhoneOrderStrategy(OrderProcessingStrategy):
def process(self, order_data):
print("Processing phone order")
# 电话订单特定逻辑
return "Phone order processed"
class StoreOrderStrategy(OrderProcessingStrategy):
def process(self, order_data):
print("Processing store order")
# 店内订单特定逻辑
return "Store order processed"
class OrderProcessor:
def __init__(self):
self.strategies = {
"online": OnlineOrderStrategy(),
"phone": PhoneOrderStrategy(),
"store": StoreOrderStrategy()
}
def process_order(self, order_type, order_data):
strategy = self.strategies.get(order_type)
if strategy:
return strategy.process(order_data)
else:
raise ValueError(f"Unknown order type: {order_type}")
def add_strategy(self, order_type, strategy):
"""动态添加新的订单处理策略"""
self.strategies[order_type] = strategy
# 使用示例
processor = OrderProcessor()
result = processor.process_order("online", {"product": "laptop", "quantity": 1})
print(result)
# 轻松添加新的订单类型
class MobileAppOrderStrategy(OrderProcessingStrategy):
def process(self, order_data):
print("Processing mobile app order")
return "Mobile app order processed"
processor.add_strategy("mobile", MobileAppOrderStrategy())
result = processor.process_order("mobile", {"product": "phone", "quantity": 1})
print(result)
设计模式的主要优点:
- 提高代码复用性:模式提供了经过验证的解决方案
- 增强代码可读性:使用标准的设计词汇
- 降低系统耦合度:通过抽象和接口减少依赖
- 提高系统可扩展性:便于添加新功能
- 促进团队协作:提供共同的设计语言
- 减少设计错误:避免重复犯同样的设计错误
1.2 面向对象设计原则
1.2.1 SOLID原则
1. 单一职责原则(Single Responsibility Principle, SRP)
定义:一个类应该只有一个引起它变化的原因。
// 违反SRP的例子
class Employee {
private String name;
private String position;
private double salary;
// 员工数据管理
public void setName(String name) { this.name = name; }
public String getName() { return name; }
// 薪资计算 - 不同职责
public double calculateSalary() {
// 复杂的薪资计算逻辑
return salary * 1.1;
}
// 报表生成 - 又一个不同职责
public String generateReport() {
return "Employee Report: " + name + ", Salary: " + calculateSalary();
}
// 数据持久化 - 第三个不同职责
public void saveToDatabase() {
// 数据库保存逻辑
System.out.println("Saving " + name + " to database");
}
}
// 遵循SRP的重构
class Employee {
private String name;
private String position;
private double salary;
// 只负责员工数据管理
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public void setPosition(String position) { this.position = position; }
public String getPosition() { return position; }
public void setSalary(double salary) { this.salary = salary; }
public double getSalary() { return salary; }
}
class SalaryCalculator {
// 专门负责薪资计算
public double calculateSalary(Employee employee) {
return employee.getSalary() * 1.1;
}
}
class EmployeeReportGenerator {
private SalaryCalculator calculator;
public EmployeeReportGenerator(SalaryCalculator calculator) {
this.calculator = calculator;
}
// 专门负责报表生成
public String generateReport(Employee employee) {
double salary = calculator.calculateSalary(employee);
return "Employee Report: " + employee.getName() + ", Salary: " + salary;
}
}
class EmployeeRepository {
// 专门负责数据持久化
public void save(Employee employee) {
System.out.println("Saving " + employee.getName() + " to database");
}
}
2. 开闭原则(Open-Closed Principle, OCP)
定义:软件实体应该对扩展开放,对修改关闭。
# 违反OCP的例子
class DiscountCalculator:
def calculate_discount(self, customer_type, amount):
if customer_type == "regular":
return amount * 0.05
elif customer_type == "premium":
return amount * 0.10
elif customer_type == "vip":
return amount * 0.15
# 添加新客户类型需要修改这个方法
return 0
# 遵循OCP的重构
from abc import ABC, abstractmethod
class DiscountStrategy(ABC):
@abstractmethod
def calculate_discount(self, amount):
pass
class RegularCustomerDiscount(DiscountStrategy):
def calculate_discount(self, amount):
return amount * 0.05
class PremiumCustomerDiscount(DiscountStrategy):
def calculate_discount(self, amount):
return amount * 0.10
class VIPCustomerDiscount(DiscountStrategy):
def calculate_discount(self, amount):
return amount * 0.15
class DiscountCalculator:
def __init__(self):
self.strategies = {}
def register_strategy(self, customer_type, strategy):
self.strategies[customer_type] = strategy
def calculate_discount(self, customer_type, amount):
strategy = self.strategies.get(customer_type)
if strategy:
return strategy.calculate_discount(amount)
return 0
# 使用示例
calculator = DiscountCalculator()
calculator.register_strategy("regular", RegularCustomerDiscount())
calculator.register_strategy("premium", PremiumCustomerDiscount())
calculator.register_strategy("vip", VIPCustomerDiscount())
# 扩展:添加新的客户类型,无需修改现有代码
class CorporateCustomerDiscount(DiscountStrategy):
def calculate_discount(self, amount):
return amount * 0.20
calculator.register_strategy("corporate", CorporateCustomerDiscount())
3. 里氏替换原则(Liskov Substitution Principle, LSP)
定义:子类对象应该能够替换其父类对象被使用。
// 违反LSP的例子
class Rectangle {
protected:
int width, height;
public:
virtual void setWidth(int w) { width = w; }
virtual void setHeight(int h) { height = h; }
virtual int getWidth() const { return width; }
virtual int getHeight() const { return height; }
virtual int getArea() const { return width * height; }
};
class Square : public Rectangle {
public:
void setWidth(int w) override {
width = height = w; // 违反了LSP
}
void setHeight(int h) override {
width = height = h; // 违反了LSP
}
};
// 这个函数期望Rectangle的行为
void testRectangle(Rectangle& rect) {
rect.setWidth(5);
rect.setHeight(4);
// 期望面积是20,但如果传入Square对象,面积会是16
assert(rect.getArea() == 20); // 对Square对象会失败
}
// 遵循LSP的重构
class Shape {
public:
virtual int getArea() const = 0;
virtual ~Shape() = default;
};
class Rectangle : public Shape {
protected:
int width, height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
void setWidth(int w) { width = w; }
void setHeight(int h) { height = h; }
int getWidth() const { return width; }
int getHeight() const { return height; }
int getArea() const override { return width * height; }
};
class Square : public Shape {
private:
int side;
public:
Square(int s) : side(s) {}
void setSide(int s) { side = s; }
int getSide() const { return side; }
int getArea() const override { return side * side; }
};
// 现在可以安全地使用多态
void testShape(const Shape& shape) {
std::cout << "Area: " << shape.getArea() << std::endl;
}
4. 接口隔离原则(Interface Segregation Principle, ISP)
定义:客户端不应该依赖它不需要的接口。
// 违反ISP的例子
interface Worker {
void work();
void eat();
void sleep();
}
class HumanWorker implements Worker {
public void work() {
System.out.println("Human working");
}
public void eat() {
System.out.println("Human eating");
}
public void sleep() {
System.out.println("Human sleeping");
}
}
class RobotWorker implements Worker {
public void work() {
System.out.println("Robot working");
}
public void eat() {
// 机器人不需要吃饭,但被迫实现
throw new UnsupportedOperationException("Robots don't eat");
}
public void sleep() {
// 机器人不需要睡觉,但被迫实现
throw new UnsupportedOperationException("Robots don't sleep");
}
}
// 遵循ISP的重构
interface Workable {
void work();
}
interface Eatable {
void eat();
}
interface Sleepable {
void sleep();
}
class HumanWorker implements Workable, Eatable, Sleepable {
public void work() {
System.out.println("Human working");
}
public void eat() {
System.out.println("Human eating");
}
public void sleep() {
System.out.println("Human sleeping");
}
}
class RobotWorker implements Workable {
public void work() {
System.out.println("Robot working");
}
// 不需要实现eat()和sleep()
}
class WorkManager {
public void manageWork(Workable worker) {
worker.work();
}
public void manageBreak(Eatable worker) {
worker.eat();
}
public void manageRest(Sleepable worker) {
worker.sleep();
}
}
5. 依赖倒置原则(Dependency Inversion Principle, DIP)
定义: - 高层模块不应该依赖低层模块,两者都应该依赖抽象 - 抽象不应该依赖细节,细节应该依赖抽象
# 违反DIP的例子
class MySQLDatabase:
def save(self, data):
print(f"Saving {data} to MySQL database")
class UserService:
def __init__(self):
self.database = MySQLDatabase() # 直接依赖具体实现
def create_user(self, user_data):
# 业务逻辑
processed_data = self.process_user_data(user_data)
self.database.save(processed_data)
def process_user_data(self, user_data):
# 处理用户数据
return f"Processed: {user_data}"
# 遵循DIP的重构
from abc import ABC, abstractmethod
class DatabaseInterface(ABC):
@abstractmethod
def save(self, data):
pass
class MySQLDatabase(DatabaseInterface):
def save(self, data):
print(f"Saving {data} to MySQL database")
class PostgreSQLDatabase(DatabaseInterface):
def save(self, data):
print(f"Saving {data} to PostgreSQL database")
class MongoDatabase(DatabaseInterface):
def save(self, data):
print(f"Saving {data} to MongoDB")
class UserService:
def __init__(self, database: DatabaseInterface):
self.database = database # 依赖抽象接口
def create_user(self, user_data):
processed_data = self.process_user_data(user_data)
self.database.save(processed_data)
def process_user_data(self, user_data):
return f"Processed: {user_data}"
# 使用示例
mysql_db = MySQLDatabase()
postgres_db = PostgreSQLDatabase()
mongo_db = MongoDatabase()
# 可以轻松切换数据库实现
user_service1 = UserService(mysql_db)
user_service2 = UserService(postgres_db)
user_service3 = UserService(mongo_db)
user_service1.create_user("John Doe")
user_service2.create_user("Jane Smith")
user_service3.create_user("Bob Johnson")
1.2.2 其他重要设计原则
1. 合成复用原则(Composition over Inheritance)
定义:优先使用对象组合,而不是类继承。
// 使用继承的方式(不推荐)
class Bird {
fly() {
console.log("Flying");
}
}
class Duck extends Bird {
swim() {
console.log("Swimming");
}
quack() {
console.log("Quack");
}
}
class Penguin extends Bird {
swim() {
console.log("Swimming");
}
fly() {
throw new Error("Penguins can't fly!"); // 问题:企鹅不会飞
}
}
// 使用组合的方式(推荐)
class FlyBehavior {
fly() {
console.log("Flying");
}
}
class NoFlyBehavior {
fly() {
console.log("Can't fly");
}
}
class SwimBehavior {
swim() {
console.log("Swimming");
}
}
class QuackBehavior {
makeSound() {
console.log("Quack");
}
}
class SilentBehavior {
makeSound() {
console.log("Silent");
}
}
class Bird {
constructor(flyBehavior, swimBehavior, soundBehavior) {
this.flyBehavior = flyBehavior;
this.swimBehavior = swimBehavior;
this.soundBehavior = soundBehavior;
}
fly() {
this.flyBehavior.fly();
}
swim() {
if (this.swimBehavior) {
this.swimBehavior.swim();
} else {
console.log("Can't swim");
}
}
makeSound() {
this.soundBehavior.makeSound();
}
// 运行时改变行为
setFlyBehavior(flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
// 使用示例
const duck = new Bird(
new FlyBehavior(),
new SwimBehavior(),
new QuackBehavior()
);
const penguin = new Bird(
new NoFlyBehavior(),
new SwimBehavior(),
new SilentBehavior()
);
duck.fly(); // Flying
duck.swim(); // Swimming
duck.makeSound(); // Quack
penguin.fly(); // Can't fly
penguin.swim(); // Swimming
penguin.makeSound(); // Silent
// 运行时改变行为
penguin.setFlyBehavior(new FlyBehavior());
penguin.fly(); // Flying (假设企鹅学会了飞)
2. 迪米特法则(Law of Demeter, LoD)
定义:一个对象应该对其他对象有最少的了解,只与直接朋友通信。
# 违反迪米特法则的例子
class Wallet:
def __init__(self, money):
self.money = money
def get_money(self):
return self.money
def set_money(self, money):
self.money = money
class Person:
def __init__(self, wallet):
self.wallet = wallet
def get_wallet(self):
return self.wallet
class Store:
def purchase(self, person, amount):
# 违反迪米特法则:Store直接操作Person的Wallet
wallet = person.get_wallet()
if wallet.get_money() >= amount:
wallet.set_money(wallet.get_money() - amount)
return True
return False
# 遵循迪米特法则的重构
class Wallet:
def __init__(self, money):
self.money = money
def has_enough_money(self, amount):
return self.money >= amount
def deduct_money(self, amount):
if self.has_enough_money(amount):
self.money -= amount
return True
return False
class Person:
def __init__(self, wallet):
self.wallet = wallet
def make_payment(self, amount):
# Person负责处理支付逻辑
return self.wallet.deduct_money(amount)
class Store:
def purchase(self, person, amount):
# Store只与Person交互,不直接操作Wallet
return person.make_payment(amount)
# 使用示例
wallet = Wallet(100)
person = Person(wallet)
store = Store()
result = store.purchase(person, 50)
print(f"Purchase successful: {result}") # True
result = store.purchase(person, 60)
print(f"Purchase successful: {result}") # False
1.3 设计模式分类
1.3.1 GoF设计模式分类
GoF将23种设计模式按照目的分为三大类:
1. 创建型模式(Creational Patterns)
目的:处理对象的创建过程
- 单例模式(Singleton):确保一个类只有一个实例
- 工厂方法模式(Factory Method):创建对象的接口,让子类决定实例化哪个类
- 抽象工厂模式(Abstract Factory):创建相关对象家族的接口
- 建造者模式(Builder):分步骤构建复杂对象
- 原型模式(Prototype):通过复制现有实例创建新对象
2. 结构型模式(Structural Patterns)
目的:处理类和对象的组合
- 适配器模式(Adapter):让不兼容的接口协同工作
- 桥接模式(Bridge):将抽象与实现分离
- 组合模式(Composite):将对象组合成树形结构
- 装饰器模式(Decorator):动态地给对象添加职责
- 外观模式(Facade):为子系统提供统一接口
- 享元模式(Flyweight):运用共享技术有效支持大量细粒度对象
- 代理模式(Proxy):为其他对象提供代理以控制对这个对象的访问
3. 行为型模式(Behavioral Patterns)
目的:处理类或对象之间的交互和职责分配
- 责任链模式(Chain of Responsibility):将请求沿着处理者链传递
- 命令模式(Command):将请求封装为对象
- 解释器模式(Interpreter):定义语言的文法表示
- 迭代器模式(Iterator):提供访问聚合对象元素的统一方法
- 中介者模式(Mediator):定义对象间的交互方式
- 备忘录模式(Memento):捕获对象内部状态
- 观察者模式(Observer):定义对象间的一对多依赖关系
- 状态模式(State):允许对象在内部状态改变时改变行为
- 策略模式(Strategy):定义算法家族并使它们可互换
- 模板方法模式(Template Method):定义算法骨架,子类实现具体步骤
- 访问者模式(Visitor):在不改变元素类的前提下定义新操作
1.3.2 按照范围分类
类模式(Class Patterns)
- 处理类和子类之间的关系
- 通过继承建立关系
- 在编译时确定关系
例子: - 工厂方法模式 - 适配器模式(类适配器) - 解释器模式 - 模板方法模式
对象模式(Object Patterns)
- 处理对象之间的关系
- 通过组合建立关系
- 在运行时确定关系,更加灵活
例子: - 抽象工厂模式 - 建造者模式 - 适配器模式(对象适配器) - 装饰器模式 - 观察者模式 - 策略模式
1.4 如何选择和应用设计模式
1.4.1 选择设计模式的考虑因素
# 设计模式选择决策树示例
class PatternSelector:
def __init__(self):
self.decision_tree = {
"object_creation": {
"single_instance": "Singleton",
"family_of_objects": "Abstract Factory",
"complex_construction": "Builder",
"clone_existing": "Prototype",
"subclass_decides": "Factory Method"
},
"object_structure": {
"incompatible_interfaces": "Adapter",
"separate_abstraction_implementation": "Bridge",
"tree_structure": "Composite",
"add_responsibilities": "Decorator",
"unified_interface": "Facade",
"share_objects": "Flyweight",
"control_access": "Proxy"
},
"object_behavior": {
"chain_of_handlers": "Chain of Responsibility",
"encapsulate_request": "Command",
"define_grammar": "Interpreter",
"traverse_collection": "Iterator",
"object_interactions": "Mediator",
"capture_state": "Memento",
"notify_dependents": "Observer",
"change_behavior": "State",
"interchangeable_algorithms": "Strategy",
"algorithm_skeleton": "Template Method",
"operations_on_structure": "Visitor"
}
}
def suggest_pattern(self, category, problem):
if category in self.decision_tree:
return self.decision_tree[category].get(problem, "No specific pattern found")
return "Invalid category"
def analyze_requirements(self, requirements):
suggestions = []
if "create" in requirements.lower():
if "single" in requirements.lower():
suggestions.append("Consider Singleton pattern")
elif "family" in requirements.lower():
suggestions.append("Consider Abstract Factory pattern")
elif "complex" in requirements.lower():
suggestions.append("Consider Builder pattern")
if "adapt" in requirements.lower() or "incompatible" in requirements.lower():
suggestions.append("Consider Adapter pattern")
if "notify" in requirements.lower() or "update" in requirements.lower():
suggestions.append("Consider Observer pattern")
if "algorithm" in requirements.lower() and "interchange" in requirements.lower():
suggestions.append("Consider Strategy pattern")
return suggestions
# 使用示例
selector = PatternSelector()
# 基于问题类型选择模式
pattern = selector.suggest_pattern("object_creation", "single_instance")
print(f"Suggested pattern: {pattern}") # Singleton
# 基于需求描述分析
requirements = "We need to create a complex object with many optional parameters"
suggestions = selector.analyze_requirements(requirements)
print(f"Pattern suggestions: {suggestions}") # Consider Builder pattern
1.4.2 应用设计模式的步骤
识别问题
- 分析当前设计中的问题
- 确定需要解决的核心问题
选择合适的模式
- 根据问题类型选择候选模式
- 比较不同模式的优缺点
适配模式到具体场景
- 根据实际需求调整模式结构
- 考虑现有代码的兼容性
实现模式
- 编写符合模式结构的代码
- 确保遵循相关的设计原则
测试和验证
- 验证模式是否解决了原问题
- 检查是否引入了新问题
文档化
- 记录模式的使用原因和方式
- 为团队成员提供参考
1.4.3 常见的反模式(Anti-patterns)
# 反模式示例:God Object(上帝对象)
class GameManager: # 违反单一职责原则的上帝对象
def __init__(self):
self.players = []
self.enemies = []
self.items = []
self.score = 0
self.level = 1
self.sound_enabled = True
self.graphics_quality = "high"
# 玩家管理
def add_player(self, player): pass
def remove_player(self, player): pass
def move_player(self, player, direction): pass
# 敌人管理
def spawn_enemy(self, enemy_type): pass
def update_enemies(self): pass
def check_enemy_collisions(self): pass
# 物品管理
def create_item(self, item_type): pass
def collect_item(self, player, item): pass
# 游戏逻辑
def update_score(self, points): pass
def check_level_complete(self): pass
def save_game(self): pass
def load_game(self): pass
# 渲染
def render_scene(self): pass
def render_ui(self): pass
# 音频
def play_sound(self, sound): pass
def set_volume(self, volume): pass
# 输入处理
def handle_keyboard_input(self): pass
def handle_mouse_input(self): pass
# 重构:使用多个专门的类
class PlayerManager:
def __init__(self):
self.players = []
def add_player(self, player):
self.players.append(player)
def remove_player(self, player):
self.players.remove(player)
def move_player(self, player, direction):
player.move(direction)
class EnemyManager:
def __init__(self):
self.enemies = []
def spawn_enemy(self, enemy_type):
# 创建敌人逻辑
pass
def update_enemies(self):
for enemy in self.enemies:
enemy.update()
class GameState:
def __init__(self):
self.score = 0
self.level = 1
def update_score(self, points):
self.score += points
def next_level(self):
self.level += 1
class Renderer:
def __init__(self, graphics_quality="high"):
self.graphics_quality = graphics_quality
def render_scene(self, game_objects):
# 渲染场景
pass
def render_ui(self, ui_elements):
# 渲染UI
pass
class AudioManager:
def __init__(self):
self.sound_enabled = True
self.volume = 1.0
def play_sound(self, sound):
if self.sound_enabled:
# 播放声音
pass
class InputHandler:
def __init__(self):
self.key_bindings = {}
def handle_input(self, input_event):
# 处理输入
pass
# 使用组合模式重构后的GameManager
class GameManager:
def __init__(self):
self.player_manager = PlayerManager()
self.enemy_manager = EnemyManager()
self.game_state = GameState()
self.renderer = Renderer()
self.audio_manager = AudioManager()
self.input_handler = InputHandler()
def update(self):
# 协调各个管理器的工作
self.enemy_manager.update_enemies()
# 其他更新逻辑
def render(self):
# 委托给渲染器
self.renderer.render_scene(self.get_all_game_objects())
self.renderer.render_ui(self.get_ui_elements())
1.5 本章总结
1.5.1 关键概念回顾
设计模式的本质
- 经过验证的设计经验总结
- 解决特定问题的通用方案
- 提供共同的设计词汇
SOLID原则
- SRP:单一职责原则
- OCP:开闭原则
- LSP:里氏替换原则
- ISP:接口隔离原则
- DIP:依赖倒置原则
设计模式分类
- 创建型模式:对象创建
- 结构型模式:对象组合
- 行为型模式:对象交互
1.5.2 学习建议
理论与实践结合
- 理解模式的理论基础
- 通过编码实践加深理解
循序渐进
- 先掌握常用模式
- 逐步学习复杂模式
关注应用场景
- 理解每个模式的适用场景
- 避免过度设计
持续重构
- 在实际项目中应用模式
- 通过重构改善代码质量
1.5.3 下章预告
下一章我们将深入学习面向对象设计基础,包括: - 类与对象的关系 - 继承、封装、多态的深入理解 - 接口与抽象类的使用 - 组合与聚合的区别 - 依赖关系的管理
这些基础知识将为后续学习具体的设计模式打下坚实的基础。
练习题
分析现有代码:找一个你熟悉的项目,识别其中违反SOLID原则的地方,并提出改进建议。
设计模式识别:在你使用的框架或库中,找出使用了哪些设计模式,分析它们解决了什么问题。
重构练习:选择一个简单的功能,先写出违反设计原则的版本,然后逐步重构,应用相关的设计原则。
模式选择:给定以下场景,选择合适的设计模式:
- 需要确保配置管理器只有一个实例
- 需要为不同的数据库提供统一的访问接口
- 需要在运行时动态改变对象的行为
- 需要将复杂子系统的接口简化
下一章:第02章:面向对象设计基础