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

典型交互流程

  1. 用户(观察者)在快递公司注册
  2. 快递状态变更时调用notify()
  3. 所有注册用户收到update通知
  4. 用户根据通知执行相应操作

设计要点

  • 主题(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表示和实现细节,能够帮助开发者在系统设计阶段做出更合理的架构决策。每种模式都针对特定类型的问题提供了优雅的解决方案,关键在于理解其适用场景和实现要点。