13.1 本章概述

在本章中,我们将深入学习两种重要的行为型设计模式:备忘录模式(Memento Pattern)解释器模式(Interpreter Pattern)。这两种模式在软件开发中有着独特的应用场景和价值。

13.1.1 学习目标

  • 理解备忘录模式的核心思想和实现机制
  • 掌握解释器模式的设计原理和应用场景
  • 学会在实际项目中合理运用这两种模式
  • 了解模式的优缺点和适用条件
  • 掌握模式的高级应用技巧和性能优化

13.1.2 应用场景预览

备忘录模式常用于: - 撤销/重做功能实现 - 游戏存档系统 - 事务回滚机制 - 配置快照管理 - 版本控制系统

解释器模式常用于: - 领域特定语言(DSL) - 配置文件解析 - 规则引擎 - 表达式求值 - 简单脚本语言


13.2 备忘录模式(Memento Pattern)

13.2.1 模式定义

备忘录模式是一种行为型设计模式,它允许在不破坏封装性的前提下,捕获并外部化一个对象的内部状态,以便以后可以将该对象恢复到原先保存的状态。

13.2.2 模式动机

在软件开发中,我们经常需要实现撤销功能,或者在某些操作失败时回滚到之前的状态。直接访问对象的内部状态会破坏封装性,而备忘录模式提供了一种优雅的解决方案。

13.2.3 模式结构

备忘录模式包含以下角色:

  1. 发起人(Originator):创建备忘录对象,用于保存当前状态
  2. 备忘录(Memento):存储发起人的内部状态
  3. 管理者(Caretaker):负责保存备忘录,但不能操作或检查备忘录的内容

13.2.4 Python实现示例:文本编辑器

from abc import ABC, abstractmethod
from typing import List, Optional
import copy
import time
from dataclasses import dataclass

# 备忘录接口
class Memento(ABC):
    """备忘录抽象基类"""
    
    @abstractmethod
    def get_state(self):
        """获取状态(仅供发起人使用)"""
        pass
    
    @abstractmethod
    def get_name(self) -> str:
        """获取备忘录名称"""
        pass
    
    @abstractmethod
    def get_date(self) -> str:
        """获取创建时间"""
        pass

# 具体备忘录
@dataclass
class TextEditorMemento(Memento):
    """文本编辑器备忘录"""
    
    def __init__(self, state: dict, name: str = ""):
        self._state = copy.deepcopy(state)
        self._name = name or f"Auto-save {time.strftime('%Y-%m-%d %H:%M:%S')}"
        self._date = time.strftime('%Y-%m-%d %H:%M:%S')
    
    def get_state(self) -> dict:
        return copy.deepcopy(self._state)
    
    def get_name(self) -> str:
        return self._name
    
    def get_date(self) -> str:
        return self._date
    
    def __str__(self):
        return f"Memento[{self._name}] - {self._date}"

# 发起人:文本编辑器
class TextEditor:
    """文本编辑器(发起人)"""
    
    def __init__(self):
        self._content = ""
        self._cursor_position = 0
        self._selection_start = 0
        self._selection_end = 0
        self._font_size = 12
        self._font_family = "Arial"
        self._is_bold = False
        self._is_italic = False
        self._zoom_level = 100
        self._word_wrap = True
        
        # 编辑历史
        self._edit_count = 0
        self._last_modified = time.time()
    
    def type_text(self, text: str):
        """输入文本"""
        # 如果有选中文本,先删除
        if self._selection_start != self._selection_end:
            self.delete_selection()
        
        # 在光标位置插入文本
        self._content = (self._content[:self._cursor_position] + 
                        text + 
                        self._content[self._cursor_position:])
        self._cursor_position += len(text)
        self._update_edit_info()
    
    def delete_text(self, count: int = 1):
        """删除文本(向后删除)"""
        if self._cursor_position > 0:
            start = max(0, self._cursor_position - count)
            self._content = (self._content[:start] + 
                           self._content[self._cursor_position:])
            self._cursor_position = start
            self._update_edit_info()
    
    def delete_selection(self):
        """删除选中的文本"""
        if self._selection_start != self._selection_end:
            start = min(self._selection_start, self._selection_end)
            end = max(self._selection_start, self._selection_end)
            
            self._content = self._content[:start] + self._content[end:]
            self._cursor_position = start
            self._selection_start = self._selection_end = start
            self._update_edit_info()
    
    def select_text(self, start: int, end: int):
        """选择文本"""
        self._selection_start = max(0, min(start, len(self._content)))
        self._selection_end = max(0, min(end, len(self._content)))
        self._cursor_position = self._selection_end
    
    def move_cursor(self, position: int):
        """移动光标"""
        self._cursor_position = max(0, min(position, len(self._content)))
        self._selection_start = self._selection_end = self._cursor_position
    
    def set_font(self, family: str, size: int, bold: bool = False, italic: bool = False):
        """设置字体"""
        self._font_family = family
        self._font_size = size
        self._is_bold = bold
        self._is_italic = italic
        self._update_edit_info()
    
    def set_zoom(self, level: int):
        """设置缩放级别"""
        self._zoom_level = max(50, min(200, level))
    
    def set_word_wrap(self, enabled: bool):
        """设置自动换行"""
        self._word_wrap = enabled
    
    def _update_edit_info(self):
        """更新编辑信息"""
        self._edit_count += 1
        self._last_modified = time.time()
    
    def save(self, name: str = "") -> Memento:
        """保存当前状态到备忘录"""
        state = {
            'content': self._content,
            'cursor_position': self._cursor_position,
            'selection_start': self._selection_start,
            'selection_end': self._selection_end,
            'font_size': self._font_size,
            'font_family': self._font_family,
            'is_bold': self._is_bold,
            'is_italic': self._is_italic,
            'zoom_level': self._zoom_level,
            'word_wrap': self._word_wrap,
            'edit_count': self._edit_count,
            'last_modified': self._last_modified
        }
        return TextEditorMemento(state, name)
    
    def restore(self, memento: Memento):
        """从备忘录恢复状态"""
        if not isinstance(memento, TextEditorMemento):
            raise ValueError("Invalid memento type")
        
        state = memento.get_state()
        self._content = state['content']
        self._cursor_position = state['cursor_position']
        self._selection_start = state['selection_start']
        self._selection_end = state['selection_end']
        self._font_size = state['font_size']
        self._font_family = state['font_family']
        self._is_bold = state['is_bold']
        self._is_italic = state['is_italic']
        self._zoom_level = state['zoom_level']
        self._word_wrap = state['word_wrap']
        self._edit_count = state['edit_count']
        self._last_modified = state['last_modified']
    
    def get_content(self) -> str:
        return self._content
    
    def get_cursor_position(self) -> int:
        return self._cursor_position
    
    def get_selection(self) -> tuple:
        return (self._selection_start, self._selection_end)
    
    def get_font_info(self) -> dict:
        return {
            'family': self._font_family,
            'size': self._font_size,
            'bold': self._is_bold,
            'italic': self._is_italic
        }
    
    def get_view_info(self) -> dict:
        return {
            'zoom_level': self._zoom_level,
            'word_wrap': self._word_wrap
        }
    
    def get_stats(self) -> dict:
        return {
            'character_count': len(self._content),
            'word_count': len(self._content.split()),
            'line_count': self._content.count('\n') + 1,
            'edit_count': self._edit_count,
            'last_modified': time.strftime('%Y-%m-%d %H:%M:%S', 
                                         time.localtime(self._last_modified))
        }
    
    def __str__(self):
        preview = self._content[:50] + "..." if len(self._content) > 50 else self._content
        return f"TextEditor[cursor={self._cursor_position}, content='{preview}']"

# 管理者:历史记录管理器
class HistoryManager:
    """历史记录管理器(管理者)"""
    
    def __init__(self, max_history: int = 50):
        self._mementos: List[Memento] = []
        self._current_index = -1
        self._max_history = max_history
        self._auto_save_enabled = True
        self._auto_save_interval = 30  # 秒
        self._last_auto_save = 0
    
    def save_state(self, memento: Memento):
        """保存状态"""
        # 如果当前不在历史记录的末尾,删除后面的记录
        if self._current_index < len(self._mementos) - 1:
            self._mementos = self._mementos[:self._current_index + 1]
        
        # 添加新的备忘录
        self._mementos.append(memento)
        self._current_index += 1
        
        # 限制历史记录数量
        if len(self._mementos) > self._max_history:
            self._mementos.pop(0)
            self._current_index -= 1
        
        print(f"状态已保存: {memento.get_name()}")
    
    def undo(self) -> Optional[Memento]:
        """撤销操作"""
        if self._current_index > 0:
            self._current_index -= 1
            memento = self._mementos[self._current_index]
            print(f"撤销到: {memento.get_name()}")
            return memento
        else:
            print("无法撤销:已到达历史记录开始")
            return None
    
    def redo(self) -> Optional[Memento]:
        """重做操作"""
        if self._current_index < len(self._mementos) - 1:
            self._current_index += 1
            memento = self._mementos[self._current_index]
            print(f"重做到: {memento.get_name()}")
            return memento
        else:
            print("无法重做:已到达历史记录末尾")
            return None
    
    def get_current_memento(self) -> Optional[Memento]:
        """获取当前备忘录"""
        if 0 <= self._current_index < len(self._mementos):
            return self._mementos[self._current_index]
        return None
    
    def get_history(self) -> List[str]:
        """获取历史记录列表"""
        history = []
        for i, memento in enumerate(self._mementos):
            marker = " -> " if i == self._current_index else "    "
            history.append(f"{marker}{i}: {memento.get_name()} ({memento.get_date()})")
        return history
    
    def clear_history(self):
        """清空历史记录"""
        self._mementos.clear()
        self._current_index = -1
        print("历史记录已清空")
    
    def can_undo(self) -> bool:
        """是否可以撤销"""
        return self._current_index > 0
    
    def can_redo(self) -> bool:
        """是否可以重做"""
        return self._current_index < len(self._mementos) - 1
    
    def set_auto_save(self, enabled: bool, interval: int = 30):
        """设置自动保存"""
        self._auto_save_enabled = enabled
        self._auto_save_interval = interval
    
    def should_auto_save(self) -> bool:
        """是否应该自动保存"""
        if not self._auto_save_enabled:
            return False
        
        current_time = time.time()
        if current_time - self._last_auto_save >= self._auto_save_interval:
            self._last_auto_save = current_time
            return True
        return False
    
    def get_stats(self) -> dict:
        """获取统计信息"""
        return {
            'total_saves': len(self._mementos),
            'current_position': self._current_index + 1,
            'can_undo': self.can_undo(),
            'can_redo': self.can_redo(),
            'auto_save_enabled': self._auto_save_enabled,
            'auto_save_interval': self._auto_save_interval
        }

# 文本编辑器应用
class TextEditorApp:
    """文本编辑器应用"""
    
    def __init__(self):
        self.editor = TextEditor()
        self.history = HistoryManager()
        
        # 保存初始状态
        initial_state = self.editor.save("初始状态")
        self.history.save_state(initial_state)
    
    def type_text(self, text: str):
        """输入文本"""
        self.editor.type_text(text)
        self._check_auto_save()
    
    def delete_text(self, count: int = 1):
        """删除文本"""
        self.editor.delete_text(count)
        self._check_auto_save()
    
    def select_and_delete(self, start: int, end: int):
        """选择并删除文本"""
        self.editor.select_text(start, end)
        self.editor.delete_selection()
        self._check_auto_save()
    
    def format_text(self, family: str, size: int, bold: bool = False, italic: bool = False):
        """格式化文本"""
        self.editor.set_font(family, size, bold, italic)
        self._check_auto_save()
    
    def save_checkpoint(self, name: str = ""):
        """手动保存检查点"""
        memento = self.editor.save(name or "手动保存")
        self.history.save_state(memento)
    
    def undo(self):
        """撤销"""
        memento = self.history.undo()
        if memento:
            self.editor.restore(memento)
    
    def redo(self):
        """重做"""
        memento = self.history.redo()
        if memento:
            self.editor.restore(memento)
    
    def _check_auto_save(self):
        """检查是否需要自动保存"""
        if self.history.should_auto_save():
            memento = self.editor.save("自动保存")
            self.history.save_state(memento)
    
    def show_status(self):
        """显示状态信息"""
        print("\n=== 编辑器状态 ===")
        print(f"内容: '{self.editor.get_content()}'")
        print(f"光标位置: {self.editor.get_cursor_position()}")
        print(f"选择范围: {self.editor.get_selection()}")
        print(f"字体信息: {self.editor.get_font_info()}")
        print(f"视图信息: {self.editor.get_view_info()}")
        print(f"统计信息: {self.editor.get_stats()}")
        
        print("\n=== 历史记录 ===")
        history = self.history.get_history()
        for record in history:
            print(record)
        
        print(f"\n=== 历史统计 ===")
        stats = self.history.get_stats()
        for key, value in stats.items():
            print(f"{key}: {value}")

# 演示备忘录模式
def demonstrate_memento_pattern():
    print("=== 备忘录模式演示:文本编辑器 ===")
    
    app = TextEditorApp()
    
    # 编辑操作
    print("\n1. 输入文本")
    app.type_text("Hello World!")
    app.save_checkpoint("输入Hello World")
    
    print("\n2. 继续编辑")
    app.type_text(" This is a test.")
    app.save_checkpoint("添加测试文本")
    
    print("\n3. 格式化文本")
    app.format_text("Times New Roman", 14, bold=True)
    app.save_checkpoint("设置字体格式")
    
    print("\n4. 选择并删除部分文本")
    app.select_and_delete(5, 11)  # 删除"World"
    app.save_checkpoint("删除World")
    
    app.show_status()
    
    # 撤销操作
    print("\n\n=== 撤销操作 ===")
    app.undo()  # 撤销删除
    app.undo()  # 撤销格式化
    app.show_status()
    
    # 重做操作
    print("\n\n=== 重做操作 ===")
    app.redo()  # 重做格式化
    app.show_status()
    
    # 测试自动保存
    print("\n\n=== 测试自动保存 ===")
    app.history.set_auto_save(True, 1)  # 1秒自动保存
    app.type_text(" Auto-save test.")
    time.sleep(1.1)
    app.type_text(" Another change.")
    app.show_status()

if __name__ == "__main__":
    demonstrate_memento_pattern()

13.2.5 Java实现示例:游戏存档系统

import java.util.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.io.*;

// 备忘录接口
interface GameMemento {
    String getName();
    LocalDateTime getTimestamp();
    GameState getState();
}

// 游戏状态数据类
class GameState implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private int level;
    private int score;
    private int lives;
    private double playerX;
    private double playerY;
    private int health;
    private int mana;
    private List<String> inventory;
    private Map<String, Integer> skills;
    private String currentMap;
    private Map<String, Object> gameFlags;
    
    public GameState() {
        this.inventory = new ArrayList<>();
        this.skills = new HashMap<>();
        this.gameFlags = new HashMap<>();
    }
    
    // 深拷贝构造函数
    public GameState(GameState other) {
        this.level = other.level;
        this.score = other.score;
        this.lives = other.lives;
        this.playerX = other.playerX;
        this.playerY = other.playerY;
        this.health = other.health;
        this.mana = other.mana;
        this.inventory = new ArrayList<>(other.inventory);
        this.skills = new HashMap<>(other.skills);
        this.currentMap = other.currentMap;
        this.gameFlags = new HashMap<>(other.gameFlags);
    }
    
    // Getters and Setters
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    
    public int getScore() { return score; }
    public void setScore(int score) { this.score = score; }
    
    public int getLives() { return lives; }
    public void setLives(int lives) { this.lives = lives; }
    
    public double getPlayerX() { return playerX; }
    public void setPlayerX(double playerX) { this.playerX = playerX; }
    
    public double getPlayerY() { return playerY; }
    public void setPlayerY(double playerY) { this.playerY = playerY; }
    
    public int getHealth() { return health; }
    public void setHealth(int health) { this.health = health; }
    
    public int getMana() { return mana; }
    public void setMana(int mana) { this.mana = mana; }
    
    public List<String> getInventory() { return new ArrayList<>(inventory); }
    public void setInventory(List<String> inventory) { this.inventory = new ArrayList<>(inventory); }
    
    public Map<String, Integer> getSkills() { return new HashMap<>(skills); }
    public void setSkills(Map<String, Integer> skills) { this.skills = new HashMap<>(skills); }
    
    public String getCurrentMap() { return currentMap; }
    public void setCurrentMap(String currentMap) { this.currentMap = currentMap; }
    
    public Map<String, Object> getGameFlags() { return new HashMap<>(gameFlags); }
    public void setGameFlags(Map<String, Object> gameFlags) { this.gameFlags = new HashMap<>(gameFlags); }
    
    @Override
    public String toString() {
        return String.format("GameState[Level=%d, Score=%d, Lives=%d, Health=%d, Position=(%.1f,%.1f)]",
                level, score, lives, health, playerX, playerY);
    }
}

// 具体备忘录实现
class ConcreteGameMemento implements GameMemento {
    private final String name;
    private final LocalDateTime timestamp;
    private final GameState state;
    
    public ConcreteGameMemento(String name, GameState state) {
        this.name = name;
        this.timestamp = LocalDateTime.now();
        this.state = new GameState(state); // 深拷贝
    }
    
    @Override
    public String getName() {
        return name;
    }
    
    @Override
    public LocalDateTime getTimestamp() {
        return timestamp;
    }
    
    @Override
    public GameState getState() {
        return new GameState(state); // 返回深拷贝
    }
    
    @Override
    public String toString() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return String.format("%s [%s]", name, timestamp.format(formatter));
    }
}

// 发起人:游戏引擎
class GameEngine {
    private GameState currentState;
    private Random random;
    
    public GameEngine() {
        this.currentState = new GameState();
        this.random = new Random();
        initializeGame();
    }
    
    private void initializeGame() {
        currentState.setLevel(1);
        currentState.setScore(0);
        currentState.setLives(3);
        currentState.setPlayerX(0.0);
        currentState.setPlayerY(0.0);
        currentState.setHealth(100);
        currentState.setMana(50);
        currentState.setCurrentMap("StartingArea");
        
        // 初始装备
        List<String> initialInventory = Arrays.asList("Sword", "Health Potion");
        currentState.setInventory(initialInventory);
        
        // 初始技能
        Map<String, Integer> initialSkills = new HashMap<>();
        initialSkills.put("Attack", 1);
        initialSkills.put("Defense", 1);
        currentState.setSkills(initialSkills);
    }
    
    // 游戏操作方法
    public void movePlayer(double deltaX, double deltaY) {
        currentState.setPlayerX(currentState.getPlayerX() + deltaX);
        currentState.setPlayerY(currentState.getPlayerY() + deltaY);
        System.out.printf("玩家移动到位置: (%.1f, %.1f)\n", 
                         currentState.getPlayerX(), currentState.getPlayerY());
    }
    
    public void gainExperience(int exp) {
        currentState.setScore(currentState.getScore() + exp);
        
        // 检查升级
        int newLevel = (currentState.getScore() / 1000) + 1;
        if (newLevel > currentState.getLevel()) {
            levelUp(newLevel);
        }
        
        System.out.printf("获得经验: %d, 总分: %d\n", exp, currentState.getScore());
    }
    
    private void levelUp(int newLevel) {
        currentState.setLevel(newLevel);
        currentState.setHealth(Math.min(100, currentState.getHealth() + 20));
        currentState.setMana(Math.min(100, currentState.getMana() + 10));
        
        // 提升技能
        Map<String, Integer> skills = currentState.getSkills();
        skills.replaceAll((k, v) -> v + 1);
        currentState.setSkills(skills);
        
        System.out.printf("恭喜升级到 %d 级!\n", newLevel);
    }
    
    public void takeDamage(int damage) {
        int newHealth = Math.max(0, currentState.getHealth() - damage);
        currentState.setHealth(newHealth);
        
        if (newHealth == 0) {
            loseLife();
        }
        
        System.out.printf("受到伤害: %d, 剩余生命值: %d\n", damage, newHealth);
    }
    
    private void loseLife() {
        int newLives = currentState.getLives() - 1;
        currentState.setLives(newLives);
        
        if (newLives > 0) {
            currentState.setHealth(100); // 复活时恢复满血
            System.out.printf("失去一条生命,剩余生命: %d\n", newLives);
        } else {
            System.out.println("游戏结束!");
        }
    }
    
    public void addItem(String item) {
        List<String> inventory = currentState.getInventory();
        inventory.add(item);
        currentState.setInventory(inventory);
        System.out.printf("获得物品: %s\n", item);
    }
    
    public void useItem(String item) {
        List<String> inventory = currentState.getInventory();
        if (inventory.remove(item)) {
            currentState.setInventory(inventory);
            
            // 使用物品效果
            switch (item) {
                case "Health Potion":
                    int newHealth = Math.min(100, currentState.getHealth() + 30);
                    currentState.setHealth(newHealth);
                    System.out.printf("使用生命药水,生命值恢复到: %d\n", newHealth);
                    break;
                case "Mana Potion":
                    int newMana = Math.min(100, currentState.getMana() + 25);
                    currentState.setMana(newMana);
                    System.out.printf("使用魔法药水,魔法值恢复到: %d\n", newMana);
                    break;
                default:
                    System.out.printf("使用了物品: %s\n", item);
            }
        } else {
            System.out.printf("背包中没有物品: %s\n", item);
        }
    }
    
    public void changeMap(String mapName) {
        currentState.setCurrentMap(mapName);
        System.out.printf("进入地图: %s\n", mapName);
    }
    
    public void setGameFlag(String flag, Object value) {
        Map<String, Object> flags = currentState.getGameFlags();
        flags.put(flag, value);
        currentState.setGameFlags(flags);
        System.out.printf("设置游戏标志: %s = %s\n", flag, value);
    }
    
    // 备忘录相关方法
    public GameMemento createSave(String saveName) {
        return new ConcreteGameMemento(saveName, currentState);
    }
    
    public void loadSave(GameMemento memento) {
        this.currentState = memento.getState();
        System.out.printf("加载存档: %s\n", memento.getName());
    }
    
    // 获取当前状态信息
    public GameState getCurrentState() {
        return new GameState(currentState);
    }
    
    public void printStatus() {
        System.out.println("\n=== 游戏状态 ===");
        System.out.println(currentState);
        System.out.printf("当前地图: %s\n", currentState.getCurrentMap());
        System.out.printf("背包物品: %s\n", currentState.getInventory());
        System.out.printf("技能等级: %s\n", currentState.getSkills());
        
        if (!currentState.getGameFlags().isEmpty()) {
            System.out.printf("游戏标志: %s\n", currentState.getGameFlags());
        }
    }
    
    public boolean isGameOver() {
        return currentState.getLives() <= 0;
    }
}

// 管理者:存档管理器
class SaveManager {
    private List<GameMemento> saves;
    private int maxSaves;
    private boolean autoSaveEnabled;
    private int autoSaveInterval; // 操作次数间隔
    private int operationCount;
    
    public SaveManager(int maxSaves) {
        this.saves = new ArrayList<>();
        this.maxSaves = maxSaves;
        this.autoSaveEnabled = true;
        this.autoSaveInterval = 5; // 每5个操作自动保存
        this.operationCount = 0;
    }
    
    public void addSave(GameMemento save) {
        saves.add(save);
        
        // 限制存档数量
        if (saves.size() > maxSaves) {
            saves.remove(0);
        }
        
        System.out.printf("存档已保存: %s\n", save.getName());
    }
    
    public GameMemento getSave(int index) {
        if (index >= 0 && index < saves.size()) {
            return saves.get(index);
        }
        return null;
    }
    
    public GameMemento getLatestSave() {
        return saves.isEmpty() ? null : saves.get(saves.size() - 1);
    }
    
    public List<GameMemento> getAllSaves() {
        return new ArrayList<>(saves);
    }
    
    public void deleteSave(int index) {
        if (index >= 0 && index < saves.size()) {
            GameMemento removed = saves.remove(index);
            System.out.printf("删除存档: %s\n", removed.getName());
        }
    }
    
    public void clearAllSaves() {
        saves.clear();
        System.out.println("所有存档已清除");
    }
    
    public void incrementOperationCount() {
        operationCount++;
    }
    
    public boolean shouldAutoSave() {
        return autoSaveEnabled && (operationCount % autoSaveInterval == 0);
    }
    
    public void setAutoSave(boolean enabled, int interval) {
        this.autoSaveEnabled = enabled;
        this.autoSaveInterval = interval;
    }
    
    public void printSaveList() {
        System.out.println("\n=== 存档列表 ===");
        if (saves.isEmpty()) {
            System.out.println("暂无存档");
        } else {
            for (int i = 0; i < saves.size(); i++) {
                System.out.printf("%d. %s\n", i + 1, saves.get(i));
            }
        }
    }
    
    public int getSaveCount() {
        return saves.size();
    }
}

// 游戏应用
class GameApplication {
    private GameEngine gameEngine;
    private SaveManager saveManager;
    
    public GameApplication() {
        this.gameEngine = new GameEngine();
        this.saveManager = new SaveManager(10);
        
        // 创建初始存档
        GameMemento initialSave = gameEngine.createSave("游戏开始");
        saveManager.addSave(initialSave);
    }
    
    public void performAction(String action, Object... params) {
        saveManager.incrementOperationCount();
        
        switch (action.toLowerCase()) {
            case "move":
                if (params.length >= 2) {
                    gameEngine.movePlayer((Double) params[0], (Double) params[1]);
                }
                break;
            case "fight":
                simulateFight();
                break;
            case "explore":
                simulateExploration();
                break;
            case "use_item":
                if (params.length >= 1) {
                    gameEngine.useItem((String) params[0]);
                }
                break;
            case "change_map":
                if (params.length >= 1) {
                    gameEngine.changeMap((String) params[0]);
                }
                break;
        }
        
        // 检查自动保存
        if (saveManager.shouldAutoSave()) {
            GameMemento autoSave = gameEngine.createSave("自动保存 #" + saveManager.getSaveCount());
            saveManager.addSave(autoSave);
        }
    }
    
    private void simulateFight() {
        Random random = new Random();
        
        // 模拟战斗
        int damage = random.nextInt(20) + 10;
        gameEngine.takeDamage(damage);
        
        if (!gameEngine.isGameOver()) {
            int exp = random.nextInt(100) + 50;
            gameEngine.gainExperience(exp);
            
            // 随机掉落物品
            if (random.nextDouble() < 0.3) {
                String[] items = {"Health Potion", "Mana Potion", "Magic Scroll", "Gold Coin"};
                String item = items[random.nextInt(items.length)];
                gameEngine.addItem(item);
            }
        }
    }
    
    private void simulateExploration() {
        Random random = new Random();
        
        // 随机移动
        double deltaX = (random.nextDouble() - 0.5) * 20;
        double deltaY = (random.nextDouble() - 0.5) * 20;
        gameEngine.movePlayer(deltaX, deltaY);
        
        // 随机事件
        double eventChance = random.nextDouble();
        if (eventChance < 0.2) {
            // 发现宝箱
            String[] treasures = {"Health Potion", "Mana Potion", "Rare Gem", "Ancient Artifact"};
            String treasure = treasures[random.nextInt(treasures.length)];
            gameEngine.addItem(treasure);
            System.out.println("发现宝箱!");
        } else if (eventChance < 0.4) {
            // 遭遇敌人
            System.out.println("遭遇敌人!");
            simulateFight();
        } else {
            // 获得少量经验
            gameEngine.gainExperience(random.nextInt(30) + 10);
        }
    }
    
    public void manualSave(String saveName) {
        GameMemento save = gameEngine.createSave(saveName);
        saveManager.addSave(save);
    }
    
    public void loadSave(int saveIndex) {
        GameMemento save = saveManager.getSave(saveIndex - 1); // 用户输入从1开始
        if (save != null) {
            gameEngine.loadSave(save);
        } else {
            System.out.println("无效的存档索引");
        }
    }
    
    public void showStatus() {
        gameEngine.printStatus();
        saveManager.printSaveList();
    }
    
    public boolean isGameOver() {
        return gameEngine.isGameOver();
    }
    
    public SaveManager getSaveManager() {
        return saveManager;
    }
}

// 演示类
public class MementoPatternDemo {
    public static void main(String[] args) {
        System.out.println("=== 备忘录模式演示:游戏存档系统 ===");
        
        GameApplication game = new GameApplication();
        
        // 游戏流程演示
        System.out.println("\n--- 开始游戏 ---");
        game.showStatus();
        
        // 进行一些游戏操作
        System.out.println("\n--- 探索和战斗 ---");
        game.performAction("explore");
        game.performAction("fight");
        game.performAction("move", 10.0, 5.0);
        game.manualSave("第一次探索后");
        
        game.performAction("explore");
        game.performAction("explore");
        game.performAction("fight");
        game.manualSave("连续探索后");
        
        game.showStatus();
        
        // 继续游戏
        System.out.println("\n--- 继续冒险 ---");
        game.performAction("change_map", "Forest");
        game.performAction("explore");
        game.performAction("fight");
        game.performAction("use_item", "Health Potion");
        
        game.showStatus();
        
        // 演示加载存档
        System.out.println("\n--- 加载之前的存档 ---");
        game.loadSave(2); // 加载"第一次探索后"存档
        game.showStatus();
        
        // 从加载点继续游戏
        System.out.println("\n--- 从存档点重新开始 ---");
        game.performAction("change_map", "Cave");
        game.performAction("explore");
        game.manualSave("洞穴探索");
        
        game.showStatus();
        
        System.out.println("\n游戏演示完成!");
    }
}

13.2.6 备忘录模式的优缺点

优点: 1. 封装性保护:不破坏对象的封装性,外部无法直接访问对象内部状态 2. 状态恢复:提供了简单的状态恢复机制 3. 撤销支持:天然支持撤销/重做功能 4. 快照管理:可以创建对象状态的快照 5. 解耦合:发起人和管理者之间解耦

缺点: 1. 内存开销:需要存储大量的状态信息 2. 性能影响:频繁创建备忘录可能影响性能 3. 复杂性增加:增加了系统的复杂性 4. 生命周期管理:需要合理管理备忘录的生命周期

13.2.7 备忘录模式的适用场景

  1. 撤销/重做功能:文本编辑器、图形编辑器等
  2. 事务处理:数据库事务回滚
  3. 游戏存档:游戏状态保存和加载
  4. 配置管理:系统配置的备份和恢复
  5. 版本控制:代码版本管理系统
  6. 工作流程:复杂业务流程的状态管理

13.3 解释器模式(Interpreter Pattern)

13.3.1 模式定义

解释器模式是一种行为型设计模式,它定义了一种语言的文法表示,并定义一个解释器来处理这种语言中的句子。该模式用于构建一个简单的语言解释器。

13.3.2 模式动机

在软件开发中,我们经常需要处理各种规则、表达式或简单的领域特定语言(DSL)。解释器模式提供了一种将语言的语法规则表示为类层次结构的方法,使得可以轻松地扩展和修改语言。

13.3.3 模式结构

解释器模式包含以下角色:

  1. 抽象表达式(AbstractExpression):定义解释操作的接口
  2. 终结符表达式(TerminalExpression):实现文法中终结符相关的解释操作
  3. 非终结符表达式(NonterminalExpression):实现文法中非终结符相关的解释操作
  4. 上下文(Context):包含解释器之外的全局信息
  5. 客户端(Client):构建抽象语法树并调用解释操作

13.3.4 Python实现示例:数学表达式解释器

from abc import ABC, abstractmethod
from typing import Dict, List, Union
import re
import math
import operator

# 上下文类
class Context:
    """解释器上下文"""
    
    def __init__(self):
        self.variables: Dict[str, float] = {}
        self.functions: Dict[str, callable] = {
            'sin': math.sin,
            'cos': math.cos,
            'tan': math.tan,
            'log': math.log,
            'sqrt': math.sqrt,
            'abs': abs,
            'pow': pow,
            'exp': math.exp
        }
        self.constants: Dict[str, float] = {
            'pi': math.pi,
            'e': math.e
        }
    
    def set_variable(self, name: str, value: float):
        """设置变量值"""
        self.variables[name] = value
    
    def get_variable(self, name: str) -> float:
        """获取变量值"""
        if name in self.variables:
            return self.variables[name]
        elif name in self.constants:
            return self.constants[name]
        else:
            raise ValueError(f"未定义的变量: {name}")
    
    def has_variable(self, name: str) -> bool:
        """检查变量是否存在"""
        return name in self.variables or name in self.constants
    
    def get_function(self, name: str) -> callable:
        """获取函数"""
        if name in self.functions:
            return self.functions[name]
        else:
            raise ValueError(f"未定义的函数: {name}")
    
    def has_function(self, name: str) -> bool:
        """检查函数是否存在"""
        return name in self.functions
    
    def clear_variables(self):
        """清空变量"""
        self.variables.clear()
    
    def get_all_variables(self) -> Dict[str, float]:
        """获取所有变量"""
        result = self.variables.copy()
        result.update(self.constants)
        return result

# 抽象表达式
class Expression(ABC):
    """抽象表达式"""
    
    @abstractmethod
    def interpret(self, context: Context) -> float:
        """解释表达式"""
        pass
    
    @abstractmethod
    def __str__(self) -> str:
        """字符串表示"""
        pass

# 终结符表达式:数字
class NumberExpression(Expression):
    """数字表达式"""
    
    def __init__(self, value: float):
        self.value = value
    
    def interpret(self, context: Context) -> float:
        return self.value
    
    def __str__(self) -> str:
        return str(self.value)

# 终结符表达式:变量
class VariableExpression(Expression):
    """变量表达式"""
    
    def __init__(self, name: str):
        self.name = name
    
    def interpret(self, context: Context) -> float:
        return context.get_variable(self.name)
    
    def __str__(self) -> str:
        return self.name

# 非终结符表达式:二元操作
class BinaryExpression(Expression):
    """二元表达式基类"""
    
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right
    
    @abstractmethod
    def operate(self, left_val: float, right_val: float) -> float:
        """执行操作"""
        pass
    
    def interpret(self, context: Context) -> float:
        left_val = self.left.interpret(context)
        right_val = self.right.interpret(context)
        return self.operate(left_val, right_val)

# 具体二元表达式
class AddExpression(BinaryExpression):
    """加法表达式"""
    
    def operate(self, left_val: float, right_val: float) -> float:
        return left_val + right_val
    
    def __str__(self) -> str:
        return f"({self.left} + {self.right})"

class SubtractExpression(BinaryExpression):
    """减法表达式"""
    
    def operate(self, left_val: float, right_val: float) -> float:
        return left_val - right_val
    
    def __str__(self) -> str:
        return f"({self.left} - {self.right})"

class MultiplyExpression(BinaryExpression):
    """乘法表达式"""
    
    def operate(self, left_val: float, right_val: float) -> float:
        return left_val * right_val
    
    def __str__(self) -> str:
        return f"({self.left} * {self.right})"

class DivideExpression(BinaryExpression):
    """除法表达式"""
    
    def operate(self, left_val: float, right_val: float) -> float:
        if right_val == 0:
            raise ValueError("除零错误")
        return left_val / right_val
    
    def __str__(self) -> str:
        return f"({self.left} / {self.right})"

class PowerExpression(BinaryExpression):
    """幂运算表达式"""
    
    def operate(self, left_val: float, right_val: float) -> float:
        return left_val ** right_val
    
    def __str__(self) -> str:
        return f"({self.left} ^ {self.right})"

# 非终结符表达式:一元操作
class UnaryExpression(Expression):
    """一元表达式基类"""
    
    def __init__(self, operand: Expression):
        self.operand = operand
    
    @abstractmethod
    def operate(self, value: float) -> float:
        """执行操作"""
        pass
    
    def interpret(self, context: Context) -> float:
        value = self.operand.interpret(context)
        return self.operate(value)

class NegateExpression(UnaryExpression):
    """取负表达式"""
    
    def operate(self, value: float) -> float:
        return -value
    
    def __str__(self) -> str:
        return f"(-{self.operand})"

# 函数调用表达式
class FunctionExpression(Expression):
    """函数调用表达式"""
    
    def __init__(self, function_name: str, arguments: List[Expression]):
        self.function_name = function_name
        self.arguments = arguments
    
    def interpret(self, context: Context) -> float:
        func = context.get_function(self.function_name)
        args = [arg.interpret(context) for arg in self.arguments]
        
        try:
            return func(*args)
        except Exception as e:
            raise ValueError(f"函数 {self.function_name} 调用错误: {e}")
    
    def __str__(self) -> str:
        args_str = ", ".join(str(arg) for arg in self.arguments)
        return f"{self.function_name}({args_str})"

# 表达式解析器
class ExpressionParser:
    """表达式解析器"""
    
    def __init__(self):
        self.operators = {
            '+': (1, AddExpression),
            '-': (1, SubtractExpression),
            '*': (2, MultiplyExpression),
            '/': (2, DivideExpression),
            '^': (3, PowerExpression)
        }
    
    def parse(self, expression: str) -> Expression:
        """解析表达式字符串"""
        tokens = self._tokenize(expression)
        return self._parse_expression(tokens)
    
    def _tokenize(self, expression: str) -> List[str]:
        """词法分析"""
        # 移除空格
        expression = re.sub(r'\s+', '', expression)
        
        # 定义token模式
        token_pattern = r'(\d+\.?\d*|[a-zA-Z_]\w*|[+\-*/^()]|,)'
        tokens = re.findall(token_pattern, expression)
        
        if not tokens:
            raise ValueError("无效的表达式")
        
        return tokens
    
    def _parse_expression(self, tokens: List[str]) -> Expression:
        """解析表达式(处理加减法)"""
        left = self._parse_term(tokens)
        
        while tokens and tokens[0] in ['+', '-']:
            op = tokens.pop(0)
            right = self._parse_term(tokens)
            
            if op == '+':
                left = AddExpression(left, right)
            else:
                left = SubtractExpression(left, right)
        
        return left
    
    def _parse_term(self, tokens: List[str]) -> Expression:
        """解析项(处理乘除法)"""
        left = self._parse_factor(tokens)
        
        while tokens and tokens[0] in ['*', '/']:
            op = tokens.pop(0)
            right = self._parse_factor(tokens)
            
            if op == '*':
                left = MultiplyExpression(left, right)
            else:
                left = DivideExpression(left, right)
        
        return left
    
    def _parse_factor(self, tokens: List[str]) -> Expression:
        """解析因子(处理幂运算、括号、函数、变量、数字)"""
        if not tokens:
            raise ValueError("意外的表达式结束")
        
        token = tokens[0]
        
        # 处理负号
        if token == '-':
            tokens.pop(0)
            operand = self._parse_factor(tokens)
            return NegateExpression(operand)
        
        # 处理括号
        if token == '(':
            tokens.pop(0)  # 移除 '('
            expr = self._parse_expression(tokens)
            if not tokens or tokens.pop(0) != ')':
                raise ValueError("缺少右括号")
            
            # 检查幂运算
            if tokens and tokens[0] == '^':
                tokens.pop(0)
                right = self._parse_factor(tokens)
                return PowerExpression(expr, right)
            
            return expr
        
        # 处理数字
        if re.match(r'^\d+\.?\d*$', token):
            tokens.pop(0)
            expr = NumberExpression(float(token))
            
            # 检查幂运算
            if tokens and tokens[0] == '^':
                tokens.pop(0)
                right = self._parse_factor(tokens)
                return PowerExpression(expr, right)
            
            return expr
        
        # 处理变量和函数
        if re.match(r'^[a-zA-Z_]\w*$', token):
            tokens.pop(0)
            
            # 检查是否是函数调用
            if tokens and tokens[0] == '(':
                tokens.pop(0)  # 移除 '('
                
                # 解析参数
                arguments = []
                if tokens and tokens[0] != ')':
                    arguments.append(self._parse_expression(tokens))
                    
                    while tokens and tokens[0] == ',':
                        tokens.pop(0)  # 移除 ','
                        arguments.append(self._parse_expression(tokens))
                
                if not tokens or tokens.pop(0) != ')':
                    raise ValueError("缺少右括号")
                
                expr = FunctionExpression(token, arguments)
            else:
                expr = VariableExpression(token)
            
            # 检查幂运算
            if tokens and tokens[0] == '^':
                tokens.pop(0)
                right = self._parse_factor(tokens)
                return PowerExpression(expr, right)
            
            return expr
        
        raise ValueError(f"无效的token: {token}")

# 数学表达式计算器
class MathCalculator:
    """数学表达式计算器"""
    
    def __init__(self):
        self.context = Context()
        self.parser = ExpressionParser()
        self.history: List[tuple] = []  # (expression_str, result)
    
    def set_variable(self, name: str, value: float):
        """设置变量"""
        self.context.set_variable(name, value)
        print(f"设置变量: {name} = {value}")
    
    def evaluate(self, expression_str: str) -> float:
        """计算表达式"""
        try:
            expression = self.parser.parse(expression_str)
            result = expression.interpret(self.context)
            
            # 记录历史
            self.history.append((expression_str, result))
            
            print(f"表达式: {expression_str}")
            print(f"解析后: {expression}")
            print(f"结果: {result}")
            
            return result
            
        except Exception as e:
            print(f"计算错误: {e}")
            raise
    
    def show_variables(self):
        """显示所有变量"""
        variables = self.context.get_all_variables()
        if variables:
            print("\n当前变量:")
            for name, value in variables.items():
                print(f"  {name} = {value}")
        else:
            print("\n暂无变量")
    
    def show_history(self):
        """显示计算历史"""
        if self.history:
            print("\n计算历史:")
            for i, (expr, result) in enumerate(self.history, 1):
                print(f"  {i}. {expr} = {result}")
        else:
            print("\n暂无计算历史")
    
    def clear_history(self):
        """清空历史"""
        self.history.clear()
        print("计算历史已清空")
    
    def clear_variables(self):
        """清空变量"""
        self.context.clear_variables()
        print("变量已清空")

# 演示解释器模式
def demonstrate_interpreter_pattern():
    print("=== 解释器模式演示:数学表达式计算器 ===")
    
    calculator = MathCalculator()
    
    # 基本运算
    print("\n1. 基本运算")
    calculator.evaluate("2 + 3 * 4")
    calculator.evaluate("(2 + 3) * 4")
    calculator.evaluate("10 / 2 - 3")
    calculator.evaluate("2 ^ 3 + 1")
    
    # 变量使用
    print("\n2. 变量使用")
    calculator.set_variable("x", 5)
    calculator.set_variable("y", 3)
    calculator.evaluate("x + y")
    calculator.evaluate("x * y - 2")
    calculator.evaluate("x ^ 2 + y ^ 2")
    
    # 函数调用
    print("\n3. 函数调用")
    calculator.evaluate("sin(pi / 2)")
    calculator.evaluate("cos(0)")
    calculator.evaluate("sqrt(16)")
    calculator.evaluate("log(e)")
    calculator.evaluate("pow(2, 3)")
    
    # 复杂表达式
    print("\n4. 复杂表达式")
    calculator.set_variable("a", 2)
    calculator.set_variable("b", 3)
    calculator.evaluate("sqrt(a^2 + b^2)")
    calculator.evaluate("sin(pi * a / 4) + cos(pi * b / 6)")
    
    # 显示状态
    calculator.show_variables()
    calculator.show_history()

if __name__ == "__main__":
    demonstrate_interpreter_pattern()

13.3.5 Go实现示例:简单查询语言

package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// Context 上下文
type Context struct {
	Data map[string]interface{}
}

// NewContext 创建新的上下文
func NewContext() *Context {
	return &Context{
		Data: make(map[string]interface{}),
	}
}

// Set 设置数据
func (c *Context) Set(key string, value interface{}) {
	c.Data[key] = value
}

// Get 获取数据
func (c *Context) Get(key string) (interface{}, bool) {
	value, exists := c.Data[key]
	return value, exists
}

// Expression 抽象表达式接口
type Expression interface {
	Interpret(context *Context) (interface{}, error)
	String() string
}

// LiteralExpression 字面量表达式
type LiteralExpression struct {
	Value interface{}
}

func (e *LiteralExpression) Interpret(context *Context) (interface{}, error) {
	return e.Value, nil
}

func (e *LiteralExpression) String() string {
	return fmt.Sprintf("%v", e.Value)
}

// VariableExpression 变量表达式
type VariableExpression struct {
	Name string
}

func (e *VariableExpression) Interpret(context *Context) (interface{}, error) {
	value, exists := context.Get(e.Name)
	if !exists {
		return nil, fmt.Errorf("变量 %s 未定义", e.Name)
	}
	return value, nil
}

func (e *VariableExpression) String() string {
	return e.Name
}

// ComparisonExpression 比较表达式
type ComparisonExpression struct {
	Left     Expression
	Operator string
	Right    Expression
}

func (e *ComparisonExpression) Interpret(context *Context) (interface{}, error) {
	leftValue, err := e.Left.Interpret(context)
	if err != nil {
		return nil, err
	}

	rightValue, err := e.Right.Interpret(context)
	if err != nil {
		return nil, err
	}

	switch e.Operator {
	case "=":
		return leftValue == rightValue, nil
	case "!=":
		return leftValue != rightValue, nil
	case ">":
		return compareNumbers(leftValue, rightValue, ">"), nil
	case "<":
		return compareNumbers(leftValue, rightValue, "<"), nil
	case ">=":
		return compareNumbers(leftValue, rightValue, ">="), nil
	case "<=":
		return compareNumbers(leftValue, rightValue, "<="), nil
	case "LIKE":
		return matchPattern(leftValue, rightValue), nil
	default:
		return nil, fmt.Errorf("不支持的操作符: %s", e.Operator)
	}
}

func (e *ComparisonExpression) String() string {
	return fmt.Sprintf("(%s %s %s)", e.Left.String(), e.Operator, e.Right.String())
}

// LogicalExpression 逻辑表达式
type LogicalExpression struct {
	Left     Expression
	Operator string
	Right    Expression
}

func (e *LogicalExpression) Interpret(context *Context) (interface{}, error) {
	leftValue, err := e.Left.Interpret(context)
	if err != nil {
		return nil, err
	}

	leftBool, ok := leftValue.(bool)
	if !ok {
		return nil, fmt.Errorf("逻辑操作需要布尔值")
	}

	switch e.Operator {
	case "AND":
		if !leftBool {
			return false, nil // 短路求值
		}
		rightValue, err := e.Right.Interpret(context)
		if err != nil {
			return nil, err
		}
		rightBool, ok := rightValue.(bool)
		if !ok {
			return nil, fmt.Errorf("逻辑操作需要布尔值")
		}
		return leftBool && rightBool, nil

	case "OR":
		if leftBool {
			return true, nil // 短路求值
		}
		rightValue, err := e.Right.Interpret(context)
		if err != nil {
			return nil, err
		}
		rightBool, ok := rightValue.(bool)
		if !ok {
			return nil, fmt.Errorf("逻辑操作需要布尔值")
		}
		return leftBool || rightBool, nil

	default:
		return nil, fmt.Errorf("不支持的逻辑操作符: %s", e.Operator)
	}
}

func (e *LogicalExpression) String() string {
	return fmt.Sprintf("(%s %s %s)", e.Left.String(), e.Operator, e.Right.String())
}

// NotExpression 非表达式
type NotExpression struct {
	Expression Expression
}

func (e *NotExpression) Interpret(context *Context) (interface{}, error) {
	value, err := e.Expression.Interpret(context)
	if err != nil {
		return nil, err
	}

	boolValue, ok := value.(bool)
	if !ok {
		return nil, fmt.Errorf("NOT操作需要布尔值")
	}

	return !boolValue, nil
}

func (e *NotExpression) String() string {
	return fmt.Sprintf("(NOT %s)", e.Expression.String())
}

// 辅助函数
func compareNumbers(left, right interface{}, operator string) bool {
	leftNum, leftOk := toFloat64(left)
	rightNum, rightOk := toFloat64(right)

	if !leftOk || !rightOk {
		return false
	}

	switch operator {
	case ">":
		return leftNum > rightNum
	case "<":
		return leftNum < rightNum
	case ">=":
		return leftNum >= rightNum
	case "<=":
		return leftNum <= rightNum
	default:
		return false
	}
}

func toFloat64(value interface{}) (float64, bool) {
	switch v := value.(type) {
	case int:
		return float64(v), true
	case int64:
		return float64(v), true
	case float32:
		return float64(v), true
	case float64:
		return v, true
	case string:
		if num, err := strconv.ParseFloat(v, 64); err == nil {
			return num, true
		}
	}
	return 0, false
}

func matchPattern(value, pattern interface{}) bool {
	valueStr, ok1 := value.(string)
	patternStr, ok2 := pattern.(string)

	if !ok1 || !ok2 {
		return false
	}

	// 简单的通配符匹配(* 表示任意字符)
	patternStr = strings.ReplaceAll(patternStr, "*", ".*")
	matched, _ := regexp.MatchString("^" + patternStr + "$", valueStr)
	return matched
}

// QueryParser 查询解析器
type QueryParser struct {
	tokens []string
	pos    int
}

// NewQueryParser 创建查询解析器
func NewQueryParser() *QueryParser {
	return &QueryParser{}
}

// Parse 解析查询字符串
func (p *QueryParser) Parse(query string) (Expression, error) {
	p.tokens = p.tokenize(query)
	p.pos = 0

	if len(p.tokens) == 0 {
		return nil, fmt.Errorf("空查询")
	}

	expr, err := p.parseOrExpression()
	if err != nil {
		return nil, err
	}

	if p.pos < len(p.tokens) {
		return nil, fmt.Errorf("查询解析不完整,剩余token: %v", p.tokens[p.pos:])
	}

	return expr, nil
}

func (p *QueryParser) tokenize(query string) []string {
	// 简单的词法分析
	query = strings.TrimSpace(query)
	pattern := `(\w+|[><=!]+|\(|\)|"[^"]*"|'[^']*')`
	re := regexp.MustCompile(pattern)
	return re.FindAllString(query, -1)
}

func (p *QueryParser) parseOrExpression() (Expression, error) {
	left, err := p.parseAndExpression()
	if err != nil {
		return nil, err
	}

	for p.pos < len(p.tokens) && strings.ToUpper(p.tokens[p.pos]) == "OR" {
		p.pos++ // 跳过 OR
		right, err := p.parseAndExpression()
		if err != nil {
			return nil, err
		}
		left = &LogicalExpression{Left: left, Operator: "OR", Right: right}
	}

	return left, nil
}

func (p *QueryParser) parseAndExpression() (Expression, error) {
	left, err := p.parseNotExpression()
	if err != nil {
		return nil, err
	}

	for p.pos < len(p.tokens) && strings.ToUpper(p.tokens[p.pos]) == "AND" {
		p.pos++ // 跳过 AND
		right, err := p.parseNotExpression()
		if err != nil {
			return nil, err
		}
		left = &LogicalExpression{Left: left, Operator: "AND", Right: right}
	}

	return left, nil
}

func (p *QueryParser) parseNotExpression() (Expression, error) {
	if p.pos < len(p.tokens) && strings.ToUpper(p.tokens[p.pos]) == "NOT" {
		p.pos++ // 跳过 NOT
		expr, err := p.parseComparisonExpression()
		if err != nil {
			return nil, err
		}
		return &NotExpression{Expression: expr}, nil
	}

	return p.parseComparisonExpression()
}

func (p *QueryParser) parseComparisonExpression() (Expression, error) {
	left, err := p.parsePrimaryExpression()
	if err != nil {
		return nil, err
	}

	if p.pos < len(p.tokens) {
		token := p.tokens[p.pos]
		if isComparisonOperator(token) {
			p.pos++
			right, err := p.parsePrimaryExpression()
			if err != nil {
				return nil, err
			}
			return &ComparisonExpression{Left: left, Operator: token, Right: right}, nil
		}
	}

	return left, nil
}

func (p *QueryParser) parsePrimaryExpression() (Expression, error) {
	if p.pos >= len(p.tokens) {
		return nil, fmt.Errorf("意外的查询结束")
	}

	token := p.tokens[p.pos]
	p.pos++

	// 处理括号
	if token == "(" {
		expr, err := p.parseOrExpression()
		if err != nil {
			return nil, err
		}
		if p.pos >= len(p.tokens) || p.tokens[p.pos] != ")" {
			return nil, fmt.Errorf("缺少右括号")
		}
		p.pos++ // 跳过 )
		return expr, nil
	}

	// 处理字符串字面量
	if (strings.HasPrefix(token, "\"") && strings.HasSuffix(token, "\"")) ||
		(strings.HasPrefix(token, "'") && strings.HasSuffix(token, "'")) {
		value := token[1 : len(token)-1] // 移除引号
		return &LiteralExpression{Value: value}, nil
	}

	// 处理数字字面量
	if num, err := strconv.ParseFloat(token, 64); err == nil {
		return &LiteralExpression{Value: num}, nil
	}

	// 处理布尔字面量
	if strings.ToLower(token) == "true" {
		return &LiteralExpression{Value: true}, nil
	}
	if strings.ToLower(token) == "false" {
		return &LiteralExpression{Value: false}, nil
	}

	// 处理变量
	return &VariableExpression{Name: token}, nil
}

func isComparisonOperator(token string) bool {
	operators := []string{"=", "!=", ">", "<", ">=", "<=", "LIKE"}
	for _, op := range operators {
		if strings.ToUpper(token) == op {
			return true
		}
	}
	return false
}

// QueryEngine 查询引擎
type QueryEngine struct {
	parser  *QueryParser
	context *Context
}

// NewQueryEngine 创建查询引擎
func NewQueryEngine() *QueryEngine {
	return &QueryEngine{
		parser:  NewQueryParser(),
		context: NewContext(),
	}
}

// SetData 设置数据
func (e *QueryEngine) SetData(key string, value interface{}) {
	e.context.Set(key, value)
}

// Query 执行查询
func (e *QueryEngine) Query(queryStr string) (interface{}, error) {
	fmt.Printf("执行查询: %s\n", queryStr)

	expr, err := e.parser.Parse(queryStr)
	if err != nil {
		return nil, fmt.Errorf("解析错误: %v", err)
	}

	fmt.Printf("解析结果: %s\n", expr.String())

	result, err := expr.Interpret(e.context)
	if err != nil {
		return nil, fmt.Errorf("执行错误: %v", err)
	}

	fmt.Printf("查询结果: %v\n\n", result)
	return result, nil
}

// ShowData 显示所有数据
func (e *QueryEngine) ShowData() {
	fmt.Println("当前数据:")
	for key, value := range e.context.Data {
		fmt.Printf("  %s = %v\n", key, value)
	}
	fmt.Println()
}

// 演示函数
func demonstrateInterpreterPattern() {
	fmt.Println("=== 解释器模式演示:简单查询语言 ===")

	engine := NewQueryEngine()

	// 设置测试数据
	engine.SetData("name", "张三")
	engine.SetData("age", 25)
	engine.SetData("salary", 8000.0)
	engine.SetData("department", "技术部")
	engine.SetData("isActive", true)
	engine.SetData("email", "zhangsan@company.com")

	engine.ShowData()

	// 基本比较查询
	fmt.Println("1. 基本比较查询")
	engine.Query("age > 20")
	engine.Query("salary >= 8000")
	engine.Query("name = '张三'")
	engine.Query("department != '销售部'")

	// 逻辑组合查询
	fmt.Println("2. 逻辑组合查询")
	engine.Query("age > 20 AND salary >= 8000")
	engine.Query("department = '技术部' OR department = '产品部'")
	engine.Query("age > 30 OR salary > 10000")

	// 复杂查询
	fmt.Println("3. 复杂查询")
	engine.Query("(age > 20 AND salary >= 8000) OR department = '管理层'")
	engine.Query("NOT (age < 18 OR salary < 5000)")
	engine.Query("isActive = true AND (age >= 25 OR salary >= 7000)")

	// 模式匹配查询
	fmt.Println("4. 模式匹配查询")
	engine.Query("email LIKE '*@company.com'")
	engine.Query("name LIKE '张*'")

	// 更新数据并重新查询
	fmt.Println("5. 更新数据后查询")
	engine.SetData("age", 30)
	engine.SetData("salary", 12000.0)
	engine.ShowData()
	engine.Query("age > 25 AND salary > 10000")
}

func main() {
	demonstrate_interpreter_pattern()
}

13.3.6 解释器模式的优缺点

优点: 1. 易于扩展:可以轻松添加新的语法规则和表达式 2. 语法清晰:每个语法规则对应一个类,结构清晰 3. 易于实现:对于简单的语言,实现相对容易 4. 灵活性高:可以动态改变和扩展语言的语法 5. 复用性好:表达式类可以在不同的上下文中复用

缺点: 1. 性能较差:对于复杂的语法,解释执行效率低 2. 类数量多:每个语法规则都需要一个类,类数量会很多 3. 维护困难:当语法规则复杂时,维护变得困难 4. 内存开销:构建抽象语法树需要大量内存 5. 调试困难:复杂的表达式树难以调试

13.3.7 解释器模式的适用场景

  1. 简单语言解释:配置文件解析、脚本语言解释
  2. 规则引擎:业务规则表达式、验证规则
  3. 查询语言:简单的查询DSL、过滤表达式
  4. 数学表达式:计算器、公式解析器
  5. 模板引擎:简单的模板语言解析
  6. 配置解析:复杂配置文件的解析和处理

13.4 备忘录模式与解释器模式对比

13.4.1 相同点

  1. 行为型模式:都属于行为型设计模式
  2. 状态管理:都涉及状态的管理和处理
  3. 封装性:都提供了良好的封装性
  4. 扩展性:都支持功能的扩展

13.4.2 不同点

特性 备忘录模式 解释器模式
主要目的 保存和恢复对象状态 解释和执行语言表达式
核心概念 状态快照 语法规则
应用场景 撤销/重做、状态回滚 语言解释、规则引擎
性能特点 内存开销大 执行效率低
复杂度 相对简单 可能很复杂
扩展方式 增加备忘录类型 增加表达式类

13.4.3 选择指南

选择备忘录模式的情况: - 需要实现撤销/重做功能 - 需要保存对象的历史状态 - 需要实现事务回滚 - 状态相对简单且变化不频繁

选择解释器模式的情况: - 需要解释简单的语言或表达式 - 需要实现规则引擎 - 语法规则相对固定且不太复杂 - 需要动态执行用户定义的规则

13.4.4 组合使用示例

from typing import List, Dict, Any
from abc import ABC, abstractmethod
import json
import copy

# 备忘录模式:保存解释器状态
class InterpreterMemento:
    """解释器备忘录"""
    
    def __init__(self, variables: Dict[str, Any], expression_history: List[str]):
        self._variables = copy.deepcopy(variables)
        self._expression_history = copy.deepcopy(expression_history)
    
    def get_variables(self) -> Dict[str, Any]:
        return copy.deepcopy(self._variables)
    
    def get_expression_history(self) -> List[str]:
        return copy.deepcopy(self._expression_history)

# 解释器上下文(发起人)
class InterpreterContext:
    """解释器上下文"""
    
    def __init__(self):
        self.variables: Dict[str, Any] = {}
        self.expression_history: List[str] = []
    
    def set_variable(self, name: str, value: Any):
        """设置变量"""
        self.variables[name] = value
    
    def get_variable(self, name: str) -> Any:
        """获取变量"""
        return self.variables.get(name)
    
    def add_expression(self, expression: str):
        """添加表达式到历史"""
        self.expression_history.append(expression)
    
    def create_memento(self) -> InterpreterMemento:
        """创建备忘录"""
        return InterpreterMemento(self.variables, self.expression_history)
    
    def restore_from_memento(self, memento: InterpreterMemento):
        """从备忘录恢复"""
        self.variables = memento.get_variables()
        self.expression_history = memento.get_expression_history()
    
    def clear(self):
        """清空状态"""
        self.variables.clear()
        self.expression_history.clear()
    
    def show_state(self):
        """显示当前状态"""
        print(f"变量: {self.variables}")
        print(f"表达式历史: {self.expression_history}")

# 备忘录管理器
class InterpreterCaretaker:
    """解释器状态管理器"""
    
    def __init__(self):
        self._mementos: List[InterpreterMemento] = []
        self._current_index = -1
    
    def save_state(self, context: InterpreterContext):
        """保存状态"""
        # 如果当前不在最新状态,删除后续的备忘录
        if self._current_index < len(self._mementos) - 1:
            self._mementos = self._mementos[:self._current_index + 1]
        
        memento = context.create_memento()
        self._mementos.append(memento)
        self._current_index += 1
        print(f"状态已保存,当前索引: {self._current_index}")
    
    def undo(self, context: InterpreterContext) -> bool:
        """撤销"""
        if self._current_index > 0:
            self._current_index -= 1
            context.restore_from_memento(self._mementos[self._current_index])
            print(f"撤销成功,当前索引: {self._current_index}")
            return True
        else:
            print("无法撤销,已到达最初状态")
            return False
    
    def redo(self, context: InterpreterContext) -> bool:
        """重做"""
        if self._current_index < len(self._mementos) - 1:
            self._current_index += 1
            context.restore_from_memento(self._mementos[self._current_index])
            print(f"重做成功,当前索引: {self._current_index}")
            return True
        else:
            print("无法重做,已到达最新状态")
            return False
    
    def show_history(self):
        """显示历史"""
        print(f"\n状态历史(共{len(self._mementos)}个状态,当前索引: {self._current_index}):")
        for i, memento in enumerate(self._mementos):
            marker = " <- 当前" if i == self._current_index else ""
            variables = memento.get_variables()
            history = memento.get_expression_history()
            print(f"  {i}: 变量={variables}, 表达式数量={len(history)}{marker}")

# 简单表达式接口
class Expression(ABC):
    """表达式接口"""
    
    @abstractmethod
    def interpret(self, context: InterpreterContext) -> Any:
        pass

# 赋值表达式
class AssignExpression(Expression):
    """赋值表达式"""
    
    def __init__(self, variable: str, value: Any):
        self.variable = variable
        self.value = value
    
    def interpret(self, context: InterpreterContext) -> Any:
        context.set_variable(self.variable, self.value)
        expression_str = f"{self.variable} = {self.value}"
        context.add_expression(expression_str)
        return self.value

# 变量表达式
class VariableExpression(Expression):
    """变量表达式"""
    
    def __init__(self, variable: str):
        self.variable = variable
    
    def interpret(self, context: InterpreterContext) -> Any:
        value = context.get_variable(self.variable)
        expression_str = f"get {self.variable}"
        context.add_expression(expression_str)
        return value

# 算术表达式
class ArithmeticExpression(Expression):
    """算术表达式"""
    
    def __init__(self, left_var: str, operator: str, right_var: str, result_var: str):
        self.left_var = left_var
        self.operator = operator
        self.right_var = right_var
        self.result_var = result_var
    
    def interpret(self, context: InterpreterContext) -> Any:
        left_val = context.get_variable(self.left_var)
        right_val = context.get_variable(self.right_var)
        
        if left_val is None or right_val is None:
            raise ValueError(f"变量未定义: {self.left_var} 或 {self.right_var}")
        
        if self.operator == "+":
            result = left_val + right_val
        elif self.operator == "-":
            result = left_val - right_val
        elif self.operator == "*":
            result = left_val * right_val
        elif self.operator == "/":
            if right_val == 0:
                raise ValueError("除零错误")
            result = left_val / right_val
        else:
            raise ValueError(f"不支持的操作符: {self.operator}")
        
        context.set_variable(self.result_var, result)
        expression_str = f"{self.result_var} = {self.left_var} {self.operator} {self.right_var}"
        context.add_expression(expression_str)
        return result

# 带状态管理的解释器
class StatefulInterpreter:
    """带状态管理的解释器"""
    
    def __init__(self):
        self.context = InterpreterContext()
        self.caretaker = InterpreterCaretaker()
        # 保存初始状态
        self.caretaker.save_state(self.context)
    
    def execute(self, expression: Expression) -> Any:
        """执行表达式"""
        try:
            result = expression.interpret(self.context)
            # 执行成功后保存状态
            self.caretaker.save_state(self.context)
            return result
        except Exception as e:
            print(f"执行错误: {e}")
            raise
    
    def undo(self) -> bool:
        """撤销操作"""
        return self.caretaker.undo(self.context)
    
    def redo(self) -> bool:
        """重做操作"""
        return self.caretaker.redo(self.context)
    
    def show_state(self):
        """显示当前状态"""
        print("\n=== 当前解释器状态 ===")
        self.context.show_state()
    
    def show_history(self):
        """显示历史"""
        self.caretaker.show_history()
    
    def reset(self):
        """重置到初始状态"""
        self.context.clear()
        self.caretaker = InterpreterCaretaker()
        self.caretaker.save_state(self.context)
        print("解释器已重置")

# 演示组合使用
def demonstrate_combined_patterns():
    print("=== 备忘录模式与解释器模式组合演示 ===")
    
    interpreter = StatefulInterpreter()
    
    print("\n1. 执行一系列表达式")
    
    # 赋值操作
    interpreter.execute(AssignExpression("x", 10))
    interpreter.show_state()
    
    interpreter.execute(AssignExpression("y", 5))
    interpreter.show_state()
    
    # 算术操作
    interpreter.execute(ArithmeticExpression("x", "+", "y", "sum"))
    interpreter.show_state()
    
    interpreter.execute(ArithmeticExpression("x", "*", "y", "product"))
    interpreter.show_state()
    
    interpreter.execute(ArithmeticExpression("sum", "/", "y", "avg"))
    interpreter.show_state()
    
    print("\n2. 显示完整历史")
    interpreter.show_history()
    
    print("\n3. 撤销操作")
    interpreter.undo()  # 撤销 avg 计算
    interpreter.show_state()
    
    interpreter.undo()  # 撤销 product 计算
    interpreter.show_state()
    
    print("\n4. 重做操作")
    interpreter.redo()  # 重做 product 计算
    interpreter.show_state()
    
    print("\n5. 继续执行新操作")
    interpreter.execute(ArithmeticExpression("product", "-", "sum", "diff"))
    interpreter.show_state()
    
    print("\n6. 最终历史状态")
    interpreter.show_history()
    
    print("\n7. 重置解释器")
    interpreter.reset()
    interpreter.show_state()
    interpreter.show_history()

if __name__ == "__main__":
    demonstrate_combined_patterns()

13.5 高级应用技巧

13.5.1 备忘录模式优化技巧

1. 增量备忘录

class IncrementalMemento:
    """增量备忘录 - 只保存变化的部分"""
    
    def __init__(self, changes: Dict[str, Any], timestamp: float):
        self.changes = changes
        self.timestamp = timestamp
    
    def apply_changes(self, state: Dict[str, Any]):
        """应用变化"""
        state.update(self.changes)
    
    def reverse_changes(self, state: Dict[str, Any], previous_values: Dict[str, Any]):
        """反向应用变化"""
        for key in self.changes:
            if key in previous_values:
                state[key] = previous_values[key]
            else:
                state.pop(key, None)

2. 压缩备忘录

import pickle
import gzip

class CompressedMemento:
    """压缩备忘录 - 减少内存占用"""
    
    def __init__(self, state: Any):
        # 序列化并压缩状态
        serialized = pickle.dumps(state)
        self._compressed_data = gzip.compress(serialized)
    
    def get_state(self) -> Any:
        """获取解压缩的状态"""
        decompressed = gzip.decompress(self._compressed_data)
        return pickle.loads(decompressed)

3. 智能备忘录管理

class SmartCaretaker:
    """智能备忘录管理器"""
    
    def __init__(self, max_mementos: int = 50, auto_cleanup: bool = True):
        self.max_mementos = max_mementos
        self.auto_cleanup = auto_cleanup
        self._mementos = []
        self._current_index = -1
    
    def save_state(self, originator):
        """智能保存状态"""
        # 自动清理旧的备忘录
        if self.auto_cleanup and len(self._mementos) >= self.max_mementos:
            self._cleanup_old_mementos()
        
        # 保存新状态
        memento = originator.create_memento()
        self._mementos.append(memento)
        self._current_index = len(self._mementos) - 1
    
    def _cleanup_old_mementos(self):
        """清理旧的备忘录"""
        # 保留最近的一半备忘录
        keep_count = self.max_mementos // 2
        self._mementos = self._mementos[-keep_count:]
        self._current_index = len(self._mementos) - 1

13.5.2 解释器模式优化技巧

1. 表达式缓存

from functools import lru_cache

class CachedExpression(Expression):
    """带缓存的表达式"""
    
    def __init__(self, expression_str: str):
        self.expression_str = expression_str
        self._parsed_expression = None
    
    @lru_cache(maxsize=128)
    def _parse_expression(self, expr_str: str):
        """缓存解析结果"""
        # 解析表达式的逻辑
        return self._do_parse(expr_str)
    
    def interpret(self, context):
        if self._parsed_expression is None:
            self._parsed_expression = self._parse_expression(self.expression_str)
        return self._parsed_expression.interpret(context)

2. 延迟求值

class LazyExpression(Expression):
    """延迟求值表达式"""
    
    def __init__(self, expression_factory):
        self.expression_factory = expression_factory
        self._expression = None
        self._evaluated = False
        self._result = None
    
    def interpret(self, context):
        if not self._evaluated:
            if self._expression is None:
                self._expression = self.expression_factory()
            self._result = self._expression.interpret(context)
            self._evaluated = True
        return self._result

3. 表达式优化器

class ExpressionOptimizer:
    """表达式优化器"""
    
    def optimize(self, expression: Expression) -> Expression:
        """优化表达式"""
        # 常量折叠
        expression = self._constant_folding(expression)
        
        # 死代码消除
        expression = self._dead_code_elimination(expression)
        
        # 公共子表达式消除
        expression = self._common_subexpression_elimination(expression)
        
        return expression
    
    def _constant_folding(self, expression: Expression) -> Expression:
        """常量折叠优化"""
        # 将常量表达式预先计算
        pass
    
    def _dead_code_elimination(self, expression: Expression) -> Expression:
        """死代码消除"""
        # 移除不会被执行的代码
        pass
    
    def _common_subexpression_elimination(self, expression: Expression) -> Expression:
        """公共子表达式消除"""
        # 提取公共子表达式
        pass

13.5.3 内存和性能优化

1. 对象池模式

class ExpressionPool:
    """表达式对象池"""
    
    def __init__(self):
        self._pools = {}
    
    def get_expression(self, expr_type: type, *args, **kwargs):
        """从池中获取表达式对象"""
        pool_key = (expr_type, args, tuple(sorted(kwargs.items())))
        
        if pool_key not in self._pools:
            self._pools[pool_key] = []
        
        pool = self._pools[pool_key]
        
        if pool:
            return pool.pop()
        else:
            return expr_type(*args, **kwargs)
    
    def return_expression(self, expression: Expression, expr_type: type, *args, **kwargs):
        """将表达式对象返回到池中"""
        pool_key = (expr_type, args, tuple(sorted(kwargs.items())))
        
        if pool_key not in self._pools:
            self._pools[pool_key] = []
        
        # 重置表达式状态
        expression.reset() if hasattr(expression, 'reset') else None
        
        self._pools[pool_key].append(expression)

2. 弱引用管理

import weakref

class WeakReferenceCaretaker:
    """使用弱引用的备忘录管理器"""
    
    def __init__(self):
        self._mementos = []
        self._weak_refs = []
    
    def save_state(self, originator):
        """保存状态(使用弱引用)"""
        memento = originator.create_memento()
        
        # 创建弱引用
        weak_ref = weakref.ref(memento, self._cleanup_callback)
        
        self._mementos.append(memento)
        self._weak_refs.append(weak_ref)
    
    def _cleanup_callback(self, weak_ref):
        """弱引用清理回调"""
        if weak_ref in self._weak_refs:
            index = self._weak_refs.index(weak_ref)
            self._weak_refs.pop(index)
            if index < len(self._mementos):
                self._mementos.pop(index)

13.6 实际应用案例

13.6.1 文档编辑器的撤销重做系统

from typing import List, Optional
import time

class DocumentMemento:
    """文档备忘录"""
    
    def __init__(self, content: str, cursor_position: int, timestamp: float):
        self._content = content
        self._cursor_position = cursor_position
        self._timestamp = timestamp
    
    def get_content(self) -> str:
        return self._content
    
    def get_cursor_position(self) -> int:
        return self._cursor_position
    
    def get_timestamp(self) -> float:
        return self._timestamp

class Document:
    """文档类(发起人)"""
    
    def __init__(self):
        self.content = ""
        self.cursor_position = 0
    
    def insert_text(self, text: str, position: Optional[int] = None):
        """插入文本"""
        if position is None:
            position = self.cursor_position
        
        self.content = self.content[:position] + text + self.content[position:]
        self.cursor_position = position + len(text)
    
    def delete_text(self, start: int, end: int):
        """删除文本"""
        self.content = self.content[:start] + self.content[end:]
        self.cursor_position = start
    
    def replace_text(self, start: int, end: int, new_text: str):
        """替换文本"""
        self.content = self.content[:start] + new_text + self.content[end:]
        self.cursor_position = start + len(new_text)
    
    def set_cursor_position(self, position: int):
        """设置光标位置"""
        self.cursor_position = max(0, min(position, len(self.content)))
    
    def create_memento(self) -> DocumentMemento:
        """创建备忘录"""
        return DocumentMemento(self.content, self.cursor_position, time.time())
    
    def restore_from_memento(self, memento: DocumentMemento):
        """从备忘录恢复"""
        self.content = memento.get_content()
        self.cursor_position = memento.get_cursor_position()
    
    def get_info(self) -> str:
        """获取文档信息"""
        return f"内容长度: {len(self.content)}, 光标位置: {self.cursor_position}"

class DocumentEditor:
    """文档编辑器"""
    
    def __init__(self):
        self.document = Document()
        self._history: List[DocumentMemento] = []
        self._current_index = -1
        self._max_history = 100
        
        # 保存初始状态
        self._save_state()
    
    def _save_state(self):
        """保存当前状态"""
        # 如果当前不在最新状态,删除后续历史
        if self._current_index < len(self._history) - 1:
            self._history = self._history[:self._current_index + 1]
        
        # 添加新状态
        memento = self.document.create_memento()
        self._history.append(memento)
        
        # 限制历史记录数量
        if len(self._history) > self._max_history:
            self._history.pop(0)
        else:
            self._current_index += 1
    
    def insert_text(self, text: str, position: Optional[int] = None):
        """插入文本"""
        self.document.insert_text(text, position)
        self._save_state()
        print(f"插入文本: '{text}' -> {self.document.get_info()}")
    
    def delete_text(self, start: int, end: int):
        """删除文本"""
        deleted_text = self.document.content[start:end]
        self.document.delete_text(start, end)
        self._save_state()
        print(f"删除文本: '{deleted_text}' -> {self.document.get_info()}")
    
    def replace_text(self, start: int, end: int, new_text: str):
        """替换文本"""
        old_text = self.document.content[start:end]
        self.document.replace_text(start, end, new_text)
        self._save_state()
        print(f"替换文本: '{old_text}' -> '{new_text}' -> {self.document.get_info()}")
    
    def undo(self) -> bool:
        """撤销"""
        if self._current_index > 0:
            self._current_index -= 1
            self.document.restore_from_memento(self._history[self._current_index])
            print(f"撤销成功 -> {self.document.get_info()}")
            return True
        else:
            print("无法撤销")
            return False
    
    def redo(self) -> bool:
        """重做"""
        if self._current_index < len(self._history) - 1:
            self._current_index += 1
            self.document.restore_from_memento(self._history[self._current_index])
            print(f"重做成功 -> {self.document.get_info()}")
            return True
        else:
            print("无法重做")
            return False
    
    def show_content(self):
        """显示文档内容"""
        content = self.document.content
        cursor_pos = self.document.cursor_position
        
        # 在光标位置插入标记
        display_content = content[:cursor_pos] + "|" + content[cursor_pos:]
        print(f"文档内容: '{display_content}'")
        print(f"信息: {self.document.get_info()}")
    
    def show_history(self):
        """显示历史记录"""
        print(f"\n历史记录(共{len(self._history)}个状态,当前索引: {self._current_index}):")
        for i, memento in enumerate(self._history):
            marker = " <- 当前" if i == self._current_index else ""
            content_preview = memento.get_content()[:20] + "..." if len(memento.get_content()) > 20 else memento.get_content()
            print(f"  {i}: '{content_preview}' (长度: {len(memento.get_content())}){marker}")

# 演示文档编辑器
def demonstrate_document_editor():
    print("=== 文档编辑器撤销重做系统演示 ===")
    
    editor = DocumentEditor()
    
    print("\n1. 初始状态")
    editor.show_content()
    
    print("\n2. 编辑操作")
    editor.insert_text("Hello")
    editor.show_content()
    
    editor.insert_text(" World")
    editor.show_content()
    
    editor.insert_text("!", 5)  # 在位置5插入
    editor.show_content()
    
    editor.replace_text(6, 11, "Python")
    editor.show_content()
    
    print("\n3. 撤销操作")
    editor.undo()
    editor.show_content()
    
    editor.undo()
    editor.show_content()
    
    print("\n4. 重做操作")
    editor.redo()
    editor.show_content()
    
    print("\n5. 继续编辑")
    editor.insert_text(" Programming")
    editor.show_content()
    
    print("\n6. 显示完整历史")
    editor.show_history()

if __name__ == "__main__":
    demonstrate_document_editor()

13.6.2 配置文件解析器

import re
from typing import Dict, Any, Union

# 配置解释器表达式
class ConfigExpression(ABC):
    """配置表达式基类"""
    
    @abstractmethod
    def interpret(self, context: Dict[str, Any]) -> Any:
        pass

class LiteralExpression(ConfigExpression):
    """字面量表达式"""
    
    def __init__(self, value: Any):
        self.value = value
    
    def interpret(self, context: Dict[str, Any]) -> Any:
        return self.value

class VariableExpression(ConfigExpression):
    """变量表达式"""
    
    def __init__(self, name: str):
        self.name = name
    
    def interpret(self, context: Dict[str, Any]) -> Any:
        if self.name in context:
            return context[self.name]
        else:
            raise ValueError(f"未定义的变量: {self.name}")

class InterpolationExpression(ConfigExpression):
    """插值表达式 ${variable}"""
    
    def __init__(self, template: str):
        self.template = template
        self.variables = re.findall(r'\$\{([^}]+)\}', template)
    
    def interpret(self, context: Dict[str, Any]) -> str:
        result = self.template
        for var in self.variables:
            if var in context:
                value = str(context[var])
                result = result.replace(f'${{{var}}}', value)
            else:
                raise ValueError(f"未定义的变量: {var}")
        return result

class ConditionalExpression(ConfigExpression):
    """条件表达式 condition ? true_value : false_value"""
    
    def __init__(self, condition: ConfigExpression, true_expr: ConfigExpression, false_expr: ConfigExpression):
        self.condition = condition
        self.true_expr = true_expr
        self.false_expr = false_expr
    
    def interpret(self, context: Dict[str, Any]) -> Any:
        condition_result = self.condition.interpret(context)
        if self._is_truthy(condition_result):
            return self.true_expr.interpret(context)
        else:
            return self.false_expr.interpret(context)
    
    def _is_truthy(self, value: Any) -> bool:
        """判断值是否为真"""
        if isinstance(value, bool):
            return value
        elif isinstance(value, (int, float)):
            return value != 0
        elif isinstance(value, str):
            return value.lower() not in ['false', '0', '', 'no', 'off']
        else:
            return bool(value)

class ComparisonExpression(ConfigExpression):
    """比较表达式"""
    
    def __init__(self, left: ConfigExpression, operator: str, right: ConfigExpression):
        self.left = left
        self.operator = operator
        self.right = right
    
    def interpret(self, context: Dict[str, Any]) -> bool:
        left_val = self.left.interpret(context)
        right_val = self.right.interpret(context)
        
        if self.operator == "==":
            return left_val == right_val
        elif self.operator == "!=":
            return left_val != right_val
        elif self.operator == ">":
            return left_val > right_val
        elif self.operator == "<":
            return left_val < right_val
        elif self.operator == ">=":
            return left_val >= right_val
        elif self.operator == "<=":
            return left_val <= right_val
        else:
            raise ValueError(f"不支持的比较操作符: {self.operator}")

class ConfigParser:
    """配置解析器"""
    
    def __init__(self):
        self.context: Dict[str, Any] = {}
    
    def set_variable(self, name: str, value: Any):
        """设置变量"""
        self.context[name] = value
    
    def parse_value(self, value_str: str) -> ConfigExpression:
        """解析配置值"""
        value_str = value_str.strip()
        
        # 检查是否是插值表达式
        if '${' in value_str:
            return InterpolationExpression(value_str)
        
        # 检查是否是条件表达式
        if '?' in value_str and ':' in value_str:
            return self._parse_conditional(value_str)
        
        # 检查是否是比较表达式
        for op in ['==', '!=', '>=', '<=', '>', '<']:
            if op in value_str:
                return self._parse_comparison(value_str, op)
        
        # 检查是否是变量引用
        if value_str.startswith('$'):
            var_name = value_str[1:]
            return VariableExpression(var_name)
        
        # 尝试解析为数字
        try:
            if '.' in value_str:
                return LiteralExpression(float(value_str))
            else:
                return LiteralExpression(int(value_str))
        except ValueError:
            pass
        
        # 解析为布尔值
        if value_str.lower() in ['true', 'yes', 'on']:
            return LiteralExpression(True)
        elif value_str.lower() in ['false', 'no', 'off']:
            return LiteralExpression(False)
        
        # 默认为字符串
        return LiteralExpression(value_str)
    
    def _parse_conditional(self, expr_str: str) -> ConditionalExpression:
        """解析条件表达式"""
        question_pos = expr_str.find('?')
        colon_pos = expr_str.find(':', question_pos)
        
        condition_str = expr_str[:question_pos].strip()
        true_str = expr_str[question_pos + 1:colon_pos].strip()
        false_str = expr_str[colon_pos + 1:].strip()
        
        condition_expr = self.parse_value(condition_str)
        true_expr = self.parse_value(true_str)
        false_expr = self.parse_value(false_str)
        
        return ConditionalExpression(condition_expr, true_expr, false_expr)
    
    def _parse_comparison(self, expr_str: str, operator: str) -> ComparisonExpression:
        """解析比较表达式"""
        parts = expr_str.split(operator, 1)
        left_str = parts[0].strip()
        right_str = parts[1].strip()
        
        left_expr = self.parse_value(left_str)
        right_expr = self.parse_value(right_str)
        
        return ComparisonExpression(left_expr, operator, right_expr)
    
    def evaluate(self, value_str: str) -> Any:
        """求值配置表达式"""
        expression = self.parse_value(value_str)
        return expression.interpret(self.context)
    
    def parse_config_file(self, config_content: str) -> Dict[str, Any]:
        """解析配置文件"""
        result = {}
        
        for line in config_content.strip().split('\n'):
            line = line.strip()
            
            # 跳过注释和空行
            if not line or line.startswith('#'):
                continue
            
            # 解析键值对
            if '=' in line:
                key, value = line.split('=', 1)
                key = key.strip()
                value = value.strip()
                
                try:
                    # 求值并存储
                    evaluated_value = self.evaluate(value)
                    result[key] = evaluated_value
                    
                    # 同时将其添加到上下文中,供后续引用
                    self.set_variable(key, evaluated_value)
                    
                except Exception as e:
                    print(f"解析配置项 '{key}' 时出错: {e}")
                    result[key] = value  # 保存原始值
        
        return result

# 演示配置解析器
def demonstrate_config_parser():
    print("=== 配置文件解析器演示 ===")
    
    parser = ConfigParser()
    
    # 设置环境变量
    parser.set_variable('ENV', 'production')
    parser.set_variable('DEBUG', False)
    parser.set_variable('PORT', 8080)
    
    # 配置文件内容
    config_content = """
# 应用配置
app_name = MyApp
version = 1.0.0

# 环境相关配置
environment = $ENV
debug_mode = $DEBUG
server_port = $PORT

# 数据库配置
db_host = ${ENV} == production ? prod-db.example.com : dev-db.example.com
db_port = ${ENV} == production ? 5432 : 5433
db_name = myapp_${ENV}

# 缓存配置
cache_enabled = ${ENV} == production ? true : false
cache_ttl = $DEBUG == true ? 60 : 3600

# 日志配置
log_level = $DEBUG == true ? DEBUG : INFO
log_file = /var/log/myapp_${ENV}.log

# 特性开关
feature_x_enabled = $version >= 1.0.0
feature_y_enabled = false
"""
    
    print("\n1. 解析配置文件")
    config = parser.parse_config_file(config_content)
    
    print("\n2. 解析结果")
    for key, value in config.items():
        print(f"  {key} = {value} ({type(value).__name__})")
    
    print("\n3. 修改环境变量并重新解析")
    parser.set_variable('ENV', 'development')
    parser.set_variable('DEBUG', True)
    
    config_dev = parser.parse_config_file(config_content)
    
    print("\n4. 开发环境配置")
    for key, value in config_dev.items():
        print(f"  {key} = {value} ({type(value).__name__})")
    
    print("\n5. 单独测试表达式")
    test_expressions = [
        "${ENV} == production ? 8080 : 3000",
        "$DEBUG == true ? verbose : normal",
        "app_${ENV}_v${version}",
        "$PORT > 8000"
    ]
    
    for expr in test_expressions:
        try:
            result = parser.evaluate(expr)
            print(f"  '{expr}' -> {result} ({type(result).__name__})")
        except Exception as e:
            print(f"  '{expr}' -> 错误: {e}")

if __name__ == "__main__":
    demonstrate_config_parser()

13.7 本章总结

13.7.1 核心概念回顾

备忘录模式: - 目的:在不破坏封装性的前提下,捕获和恢复对象的内部状态 - 核心组件:发起人(Originator)、备忘录(Memento)、管理者(Caretaker) - 关键特性:状态保存、状态恢复、封装保护

解释器模式: - 目的:定义语言的文法表示,并提供解释器来处理语言中的句子 - 核心组件:抽象表达式、终结符表达式、非终结符表达式、上下文 - 关键特性:语法解析、表达式求值、语言扩展

13.7.2 最佳实践

  1. 备忘录模式最佳实践:

    • 合理控制备忘录的数量,避免内存溢出
    • 使用增量备忘录减少内存占用
    • 实现智能清理机制
    • 考虑使用压缩技术
    • 提供批量操作的撤销功能
  2. 解释器模式最佳实践:

    • 保持语法简单,避免过度复杂
    • 使用缓存优化重复解析
    • 实现表达式优化器
    • 提供良好的错误处理
    • 考虑使用访问者模式进行语法树遍历

13.7.3 实际应用建议

  1. 选择合适的场景:

    • 备忘录模式适用于需要撤销/重做功能的应用
    • 解释器模式适用于需要处理简单DSL的场景
  2. 性能考虑:

    • 备忘录模式要注意内存管理
    • 解释器模式要注意执行效率
  3. 扩展性设计:

    • 预留扩展接口
    • 使用组合模式增强灵活性

13.7.4 注意事项

  1. 内存管理:

    • 及时清理不需要的备忘录
    • 使用弱引用避免内存泄漏
    • 实现内存使用监控
  2. 性能优化:

    • 使用对象池减少对象创建开销
    • 实现延迟加载和缓存机制
    • 避免深度递归导致的栈溢出
  3. 错误处理:

    • 提供详细的错误信息
    • 实现优雅的降级机制
    • 添加调试和日志功能

13.8 练习题

13.8.1 基础练习

  1. 备忘录模式练习:

    • 实现一个简单的画图程序,支持撤销/重做功能
    • 为游戏角色实现存档/读档系统
    • 创建一个支持历史记录的计算器
  2. 解释器模式练习:

    • 实现一个简单的布尔表达式解释器
    • 创建一个基本的SQL WHERE子句解释器
    • 设计一个配置文件表达式解析器

13.8.2 进阶练习

  1. 组合应用:

    • 结合备忘录模式和解释器模式,实现一个支持撤销的脚本执行器
    • 创建一个可视化的表达式编辑器,支持拖拽构建和撤销操作
    • 实现一个支持版本控制的配置管理系统
  2. 性能优化:

    • 为备忘录模式实现增量保存和压缩功能
    • 为解释器模式添加表达式缓存和优化功能
    • 实现内存使用监控和自动清理机制

13.8.3 思考题

  1. 如何在分布式系统中实现备忘录模式?
  2. 解释器模式与编译器设计有什么关系?
  3. 如何结合其他设计模式来增强备忘录模式和解释器模式的功能?
  4. 在什么情况下应该选择解释器模式而不是策略模式?
  5. 如何设计一个支持并发访问的备忘录系统?

下一章预告: 在下一章中,我们将学习模板方法模式与工厂方法模式的高级应用,探讨如何通过这两种模式实现更灵活的算法框架和对象创建机制,以及它们在实际项目中的最佳实践。