GoF 23种设计模式实战解析:从工厂到策略的5个经典案例UML图
GoF 23种设计模式实战解析:从工厂到策略的5个经典案例UML图
在软件开发领域,设计模式如同建筑师的蓝图,为解决常见问题提供了经过验证的解决方案。本文将深入探讨五种经典设计模式的实际应用,通过完整的UML类图展示其设计思路,帮助开发者掌握从理论到实践的转化技巧。
1. 工厂模式:游戏角色生成系统
游戏开发中经常需要动态创建不同类型的角色。假设我们正在开发一款RPG游戏,需要生成不同等级的战士和怪物。使用抽象工厂模式可以优雅地解决这个问题。
@startuml class GameFactory { +createFighter(): Fighter +createMonster(): Monster } class BeginnerFactory { +createFighter(): Fighter +createMonster(): Monster } class AdvancedFactory { +createFighter(): Fighter +createMonster(): Monster } class Fighter { +attack(): void } class Monster { +defend(): void } class BeginnerFighter class AdvancedFighter class BeginnerMonster class AdvancedMonster GameFactory <|-- BeginnerFactory GameFactory <|-- AdvancedFactory Fighter <|-- BeginnerFighter Fighter <|-- AdvancedFighter Monster <|-- BeginnerMonster Monster <|-- AdvancedMonster BeginnerFactory --> BeginnerFighter BeginnerFactory --> BeginnerMonster AdvancedFactory --> AdvancedFighter AdvancedFactory --> AdvancedMonster @enduml关键设计决策:
- 抽象工厂接口定义了创建产品族的方法
- 具体工厂实现负责创建特定等级的角色
- 产品接口确保所有具体产品具有统一行为
开闭原则体现:
- 新增角色等级只需添加新工厂类,无需修改现有代码
- 客户端代码仅依赖抽象接口,与具体实现解耦
2. 策略模式:电影院票价折扣系统
电影院售票系统需要为不同类型用户提供差异化折扣策略。策略模式允许在运行时灵活切换算法。
@startuml class Ticket { -price: double -discount: DiscountStrategy +getPrice(): double +setDiscount(d: DiscountStrategy): void } interface DiscountStrategy { +calculate(price: double): double } class StudentDiscount { +calculate(price: double): double } class VIPDiscount { +calculate(price: double): double } class ChildrenDiscount { +calculate(price: double): double } Ticket o-- DiscountStrategy DiscountStrategy <|.. StudentDiscount DiscountStrategy <|.. VIPDiscount DiscountStrategy <|.. ChildrenDiscount @enduml策略对比表:
| 策略类型 | 折扣率 | 适用场景 |
|---|---|---|
| 学生票 | 20% off | 需验证学生证 |
| VIP票 | 50% off + 积分 | 会员用户 |
| 儿童票 | 固定减10元 | 12岁以下 |
模式优势:
- 避免使用复杂的条件判断语句
- 新增折扣策略不影响现有代码
- 算法实现细节对客户端透明
3. 观察者模式:快递通知系统
电商平台需要实时通知用户快递状态变化。观察者模式建立了对象间的一对多依赖关系。
@startuml class ExpressCompany { -observers: List<Observer> +register(o: Observer): void +notify(): void } interface Observer { +update(info: string): void } class Student { +update(info: string): void } class Teacher { +update(info: string): void } ExpressCompany o-- Observer Observer <|.. Student Observer <|.. Teacher @enduml典型交互流程:
- 用户(观察者)在快递公司注册
- 快递状态变更时调用notify()
- 所有注册用户收到update通知
- 用户根据通知执行相应操作
设计要点:
- 主题(ExpressCompany)维护观察者列表
- 观察者接口统一了通知方式
- 支持动态添加/移除观察者
4. 装饰器模式:游戏角色装备系统
RPG游戏中角色装备会动态影响属性。装饰器模式可以在运行时透明地添加功能。
@startuml class Character { +attack(): int +defense(): int } class Warrior { +attack(): int +defense(): int } class Equipment { -character: Character +attack(): int +defense(): int } class Sword { +attack(): int } class Shield { +defense(): int } Character <|-- Warrior Character <|-- Equipment Equipment <|-- Sword Equipment <|-- Shield @enduml装备叠加效果:
base = Warrior() sword_warrior = Sword(base) shield_sword_warrior = Shield(sword_warrior) print(shield_sword_warrior.attack()) # 基础攻击 + 剑加成 print(shield_sword_warrior.defense()) # 基础防御 + 盾加成模式特点:
- 比继承更灵活的功能扩展方式
- 装饰器与被装饰对象实现相同接口
- 可以递归嵌套多个装饰器
5. 状态模式:播放器控制系统
媒体播放器需要根据当前状态改变行为。状态模式将状态转移逻辑封装在独立类中。
@startuml class Player { -state: State +play(): void +pause(): void +stop(): void } interface State { +play(p: Player): void +pause(p: Player): void +stop(p: Player): void } class PlayingState { +play(p: Player): void +pause(p: Player): void +stop(p: Player): void } class PausedState { +play(p: Player): void +pause(p: Player): void +stop(p: Player): void } class StoppedState { +play(p: Player): void +pause(p: Player): void +stop(p: Player): void } Player o-- State State <|.. PlayingState State <|.. PausedState State <|.. StoppedState @enduml状态转移矩阵:
| 当前状态 | play() | pause() | stop() |
|---|---|---|---|
| Stopped | →Playing | 无效 | 无效 |
| Playing | 无效 | →Paused | →Stopped |
| Paused | →Playing | 无效 | →Stopped |
实现提示:
- 每个状态类封装该状态下的行为
- 上下文(Player)将请求委托给当前状态
- 状态转移由具体状态类控制
掌握这些设计模式的UML表示和实现细节,能够帮助开发者在系统设计阶段做出更合理的架构决策。每种模式都针对特定类型的问题提供了优雅的解决方案,关键在于理解其适用场景和实现要点。
