跳至正文

游戏开发的设计模式之MVC+策略组合

一. MVC 能解决的问题

维度 当前问题 MVC 改进
代码组织 UI和逻辑混在一个类 View负责UI操作,Controller负责逻辑
可读性 一个类300+行,混杂各种逻辑 分离后各自职责清晰
维护性 改UI要找半天逻辑代码 改动UI不影响逻辑

二. MVC 的局限性

MVC 主要解决 "UI和逻辑耦合" 的问题,但对于 "多模式分支判断" 的问题,单纯用MVC改善有限。

例如:在游戏开发中,UI 界面经常需要处理多种游戏模式的逻辑。以游戏结束界面为例:

  • 经典模式:有好友分享、皮肤解锁、金币奖励等完整逻辑
  • 挑战模式:无分享、无皮肤解锁、无金币奖励的结算流程

如果使用传统的 if (isMode === ModeA) { ... } else { ... } 模式判断,会导致:

  • 代码逻辑分散在各处,难以维护
  • 新增模式时需要修改所有判断位置
  • 测试困难,难以单独验证某模式的逻辑

三. 解决方案

采用 MVC + 策略模式 的组合来解决多模式 UI 逻辑问题。

3.1 设计思路

┌───────────────────────────────────────────┐
│                         View                                                                                                              │
│  (OverLayer) - 纯 UI 渲染,不包含业务逻辑                                                                              │
└───────────────────────────────────────────┘
                            ▲
                           │ 调用
                           │
┌───────────────────────────────────────────┐
│                     Controller                                                                                                          │
│  (OverController) - 流程编排,协调 View 和 Strategy                                                               │
└───────────────────────────────────────────┘
                            ▲
                           │ 调用
                           │
┌───────────────────────────────────────────┐
│                      Strategy                                                                                                            │
│  (IOverStrategy) - 接口定义                                                                                                     │
│  (OverBaseStrategy) - 基类,通用逻辑                                                                                     │
│  (OverClassicStrategy / OverChallStrategy) - 各模式实现                                                          │
└───────────────────────────────────────────┘

3.2 职责划分

View(视图层)

职责

  • UI 组件的显示/隐藏、状态更新
  • 接收用户事件,传递给 Controller
  • 不包含任何业务逻辑判断

特点

  • 实现预定义的视图接口(IOverView)
  • 通过 Controller 间接获取数据
  • 被动等待被调用

Controller(控制器)

职责

  • 流程编排,确定调用顺序
  • 获取全局数据(如排行榜名称)
  • 控制 View 的加载状态
  • 不包含具体业务逻辑

特点

  • 持有 View 和 Strategy 的引用
  • 协调两者之间的配合
  • 适合放置"显示 loading → 调用策略 → 显示结果"这类编排逻辑

Strategy(策略层)

职责

  • 所有业务逻辑判断(模式差异的核心)
  • 调用 View 的时机控制
  • 模式特有的数据处理

特点

  • 实现统一接口,保证一致性
  • 通过依赖注入获得 View 引用
  • 可以直接调用 View 的方法
// 策略接口示例
interface IOverStrategy {
    readonly mode: EGameMode;
    handleOverGold(score: number): void;
    // ...
}

// 基类实现通用逻辑
abstract class OverBaseStrategy implements IOverStrategy {
    protected _view: IOverView | null = null;
    // ...
}

// 经典模式特有处理
class OverClassicStrategy extends OverBaseStrategy {
    handleOverGold(score: number): void {
        // ...
    }
}

// 模式挑战特有处理
class OverChallStrategy extends OverBaseStrategy {
    handleOverGold(score: number): void {
        // 挑战模式不显示金币弹窗
    }
}

3.3 模块架构

game/
├── controller/
│   └── OverController.ts      # 控制器类
├── strategy/
│   ├── IOverStrategy.ts       # 策略接口
│   ├── OverBaseStrategy.ts     # 策略基类(通用逻辑)
│   ├── OverClassicStrategy.ts  # 经典模式策略
│   └── OverChallStrategy.ts   # 挑战模式策略
├── ui/
│   └── OverLayer.ts           # 视图类(实现 IOverView)
└── factory/
    └── OverStrategyFactory.ts  # 策略工厂(可选)

3.4 适用场景

  1. UI 界面需要支持多种游戏模式
  2. 不同模式有相似的流程但具体实现不同
  3. 预期会有新的模式扩展
  4. 需要方便单独测试和修改某模式的逻辑

3.5 不适用场景

  • 简单页面,逻辑简单且不会扩展
  • 单一模式的页面,直接写在一起反而更清晰

3.6 注意事项

1. Strategy 依赖 View

Strategy 需要调用 View 方法,因此会依赖 View 接口。这在 Strategy 模式中是正常的 —— 策略需要知道如何展示结果。

2. 避免循环依赖

View → Controller → Strategy → View

为避免循环依赖:

  • View 通过接口与 Strategy 交互
  • Controller 负责初始化和协调
  • 不要在 Strategy 中直接创建 View 实例

3. 接口的演进

随着需求变化,策略接口可能需要新增方法。注意:

  • 新增方法时,所有实现类都需要实现
  • 可以考虑使用默认参数或空实现来减少实现类的工作量

4. 工厂模式的使用

当策略创建逻辑复杂时,可以使用工厂类:

class OverStrategyFactory {
    static create(mode: EGameMode): IOverStrategy {
        switch (mode) {
            case EGameMode.Classic:
                return new OverClassicStrategy();
            case EGameMode.Chall:
                return new OverChallStrategy();
            default:
                throw new Error(`Unknown mode: ${mode}`);
        }
    }
}

四 总结

MVC + 策略模式的组合适用于:

  • ✅ 多模式 UI 需要差异化处理
  • ✅ 需要方便扩展新模式
  • ✅ 业务逻辑需要与 UI 渲染分离

核心原则:

  1. View 只负责 UI 渲染
  2. Controller 只负责流程编排
  3. Strategy 包含所有业务逻辑,并决定何时调用 View
标签:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注