备忘录、迭代器和解释器模式(行为型设计模式)的 C++ 代码示例模板

2023-12-24 11:44:22

前言

备忘录、迭代器和解释器模式(行为型设计模式)的 C++ 代码示例模板。


代码仓库


备忘录模式(Memento)

结构

  • 备忘录类(保存 发起者对象 的状态)
  • 发起者类(需要保存和恢复状态 的对象)
  • 管理者类(管理备忘录对象)
  • 备忘录类 封装 状态属性,保存状态方法,获取状态方法
  • 发起者类 封装 状态属性,设置状态方法,创建备忘录(保存状态)方法(将状态交给备忘录保存),恢复备忘录(恢复状态)方法(从备忘录获取/恢复状态)
  • 管理者类 封装 添加备忘录方法,获取备忘录方法
  • 备忘录过程:发起者 调用 创建备忘录(保存状态)方法 -> 管理者 调用 添加备忘录方法;管理者 调用 获取备忘录方法 -> 发起者 调用 恢复备忘录(恢复状态)方法
  • 基于嵌套类的实现中,备忘录类 是 发起者类 的内部类,发起者类 管理 备忘录类 的创建和恢复,通常不需要管理者类

类型:

  • 基于非嵌套类/接口的实现:支持和不支持嵌套类的编程语言(如 PHP) 可以实现
  • 基于嵌套类的实现:只能在 支持嵌套类的编程语言(如 C++、 C# 和 Java) 实现

代码(基于非嵌套类/接口的实现)

#include <string>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

// 备忘录类(保存 发起者对象 的状态)
// 备忘录类 封装 状态属性,保存状态方法,获取状态方法
class Memento
{
public:
    Memento(string state) : state(state) {} // 保存状态

    // 设置状态

    // 获取状态
    string get_state()
    {
        return this->state;
    }

private:
    string state; // 状态
};

// 发起者类(需要保存和恢复状态 的对象)
// 发起者类 封装 状态属性,设置状态方法,创建备忘录(保存状态)方法(将状态交给备忘录保存),恢复备忘录(恢复状态)方法(从备忘录获取/恢复状态)
class Initiator
{
public:
    // 设置状态
    void set_state(string state)
    {
        this->state = state;
        cout << "Current state: " << this->state << endl;
    }

    // 获取状态

    // 创建备忘录(保存状态)
    Memento create_memento()
    {
        return Memento(this->state); // 将状态交给备忘录保存
    }

    // 恢复备忘录(恢复状态)
    void restore_memento(Memento memento)
    {
        this->state = memento.get_state(); // 从备忘录获取/恢复状态
        cout << "State restores to: " << this->state << endl;
    }

private:
    string state; // 状态
};

// 管理者类(管理备忘录对象)
// 管理者类 封装 添加备忘录方法,获取备忘录方法
class Administrator
{
public:
    // 添加备忘录
    void add_memento(Memento memento)
    {
        this->memento_vec.push_back(memento);
    }

    // 获取备忘录
    const Memento get_memento(int index)
    {
        return this->memento_vec.at(index);
    }

private:
    vector<Memento> memento_vec;
};

// 客户端
int main()
{
    // 发起者对象
    Initiator initiator;
    // 管理者对象
    Administrator administrator;

    initiator.set_state("State 1"); // 设置状态
    // 备忘录对象
    Memento memento_1 = initiator.create_memento(); // 1. 创建备忘录(保存状态)
    administrator.add_memento(memento_1);           // 2. 添加备忘录

    initiator.set_state("State 2");                   // 设置状态
    Memento memento_2 = administrator.get_memento(0); // 3. 获取备忘录
    initiator.restore_memento(memento_2);             // 4. 恢复备忘录(恢复状态)
    // 备忘录过程:
    // 发起者 调用 创建备忘录(保存状态)方法 -> 管理者 调用 添加备忘录方法
    // 管理者 调用 获取备忘录方法 -> 发起者 调用 恢复备忘录(恢复状态)方法

    return 0;
}
/*
输出:
Current state: State 1
Current state: State 2
State restores to: State 1
*/

代码(基于嵌套类的实现)

#include <string>
#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

// 发起者类(需要保存和恢复状态 的对象)
// 发起者类 封装 状态属性,设置状态方法,创建备忘录(保存状态)方法(将状态交给备忘录保存),恢复备忘录(恢复状态)方法(从备忘录获取/恢复状态)
class Initiator
{
public:
    // 备忘录类(保存 发起者对象 的状态)
    // 备忘录类 封装 状态属性,保存状态方法,获取状态方法
    class Memento
    {
    public:
        Memento(string state) : state(state) {} // 保存状态

        // 设置状态

        // 获取状态
        string get_state()
        {
            return this->state;
        }

    private:
        string state; // 状态
    };

public:
    // 设置状态
    void set_state(string state)
    {
        this->state = state;
        cout << "Current state: " << this->state << endl;
    }

    // 获取状态

    // 创建备忘录(保存状态)
    Memento create_memento()
    {
        return Memento(this->state); // 将状态交给备忘录保存
    }

    // 恢复备忘录(恢复状态)
    void restore_memento(Memento memento)
    {
        this->state = memento.get_state(); // 从备忘录获取/恢复状态
        cout << "State restores to: " << this->state << endl;
    }

private:
    string state; // 状态
};

// 基于嵌套类的实现中,备忘录类 是 发起者类 的内部类,发起者类 管理 备忘录类 的创建和恢复,通常不需要管理者类

// 客户端
int main()
{
    // 发起者对象
    Initiator initiator;

    initiator.set_state("State 1"); // 设置状态
    // 备忘录对象
    Initiator::Memento memento_1 = initiator.create_memento(); // 1. 创建备忘录(保存状态)

    initiator.set_state("State 2");       // 设置状态
    initiator.restore_memento(memento_1); // 2. 恢复备忘录(恢复状态)

    return 0;
}
/*
输出:
Current state: State 1
Current state: State 2
State restores to: State 1
*/

迭代器模式(Iterator)

结构

  • 项目类(需要迭代 的对象)
  • 抽象迭代器类
  • 具体迭代器类(帮助迭代 的对象)
  • 抽象聚合类
  • 具体聚合类(连接 项目集合 和 迭代器,获取 并 使用 项目集合 创建 迭代器)
  • 抽象迭代器类 封装 获取第一个项目方法 和 获取下一个项目方法
  • 具体迭代器类 封装 项目指针(实际上指向一个项目对象)的集合属性 和 项目集合的当前索引属性
  • 具体迭代器类 重写 获取第一个项目方法 和 获取下一个项目方法
  • 抽象聚合类 封装 创建迭代器方法
  • 具体聚合类 封装 项目指针(实际上指向一个项目对象)的集合属性 和 重写 创建迭代器方法(抽象迭代器指针类型 的 具体迭代器指针)

代码

#include <string>
#include <vector>
#include <iostream>

using std::cout;
using std::endl;
using std::string;
using std::vector;

// 项目类(需要迭代 的对象)
class Item
{
public:
    Item(string name) : name(name) {}

    // 获取名称
    string get_name()
    {
        return this->name;
    }

private:
    string name; // 名称
};

// 抽象迭代器类
class AbstractIterator
{
public:
    virtual Item *get_first() = 0; // 获取第一个项目
    virtual Item *get_next() = 0;  // 获取下一个项目
};

// 具体迭代器类(帮助迭代 的对象)
class ConcreteIterator : public AbstractIterator
{
public:
    ConcreteIterator(vector<Item *> item_vec) : item_vec(item_vec), cur_index(0) {}

    // 获取第一个项目
    Item *get_first() override
    {
        Item *item = this->item_vec[0];

        if (item != nullptr) // 有第一个项目
        {
            return item; // 返回第一个项目
        }
        else // 无第一个项目
        {
            return nullptr; // 返回空指针
        }
    }

    // 获取下一个项目
    Item *get_next() override
    {
        if ((this->cur_index < (this->item_vec.size() - 1)) == true)
        // 索引 = 大小 - 1
        // 如果 项目的当前索引 小于 项目集合的大小 - 1,返回 true,有下一个项目
        // 如果 项目的当前索引 等于或大于 项目集合的大小 - 1,返回 false,无下一个项目
        {
            ++this->cur_index;
            Item *item = this->item_vec[this->cur_index];

            return item;
        }
        else
        {
            return nullptr;
        }
    }

private:
    vector<Item *> item_vec; // 项目指针(实际上指向一个项目对象)的集合
    size_t cur_index;        // 项目集合的当前索引
};

// 抽象聚合类
class AbstractAggregate
{
public:
    virtual AbstractIterator *create_iterator() = 0; // 创建迭代器
};

// 具体聚合类(连接 项目集合 和 迭代器,获取 并 使用 项目集合 创建 迭代器)
class ConcreteAggregate : public AbstractAggregate
{
public:
    ConcreteAggregate(vector<Item *> item_vec) : item_vec(item_vec) {}

    // 创建迭代器(抽象迭代器指针类型 的 具体迭代器指针)
    AbstractIterator *create_iterator() override
    {
        return new ConcreteIterator(this->item_vec);
    }

private:
    vector<Item *> item_vec;
};

// 客户端
int main()
{
    // 项目对象的集合
    Item *item_1 = new Item("Item1");
    Item *item_2 = new Item("Item2");
    Item *item_3 = new Item("Item3");
    vector<Item *> item_vec = {item_1, item_2, item_3};

    // 具体聚合对象
    ConcreteAggregate aggregate(item_vec);

    // 抽象迭代器指针类型 的 具体迭代器指针
    AbstractIterator *iterator = aggregate.create_iterator(); // 创建迭代器

    // 使用 具体迭代器指针 遍历 项目对象的集合
    for (Item *item = iterator->get_first(); item != nullptr; item = iterator->get_next())
    {
        cout << "Item: " << item->get_name() << endl;
    }

    delete iterator;
    for (Item *item : item_vec)
    {
        delete item;
    }

    return 0;
}
/*
输出:
Item: Item1
Item: Item2
Item: Item3
*/

解释器模式(Interpreter)

结构

  • 抽象表达式类
  • 终结符表达式类 (树叶结点;用于将 变量 解释为 值)
  • 非终结符表达式类 (树枝结点;用于将 表达式 解释为 操作)
  • 上下文类(用于 设置 变量和值的映射 和 获取 变量 映射的 值)
  • 抽象表达式类 封装 解释方法
  • 终结符表达式类 封装 变量 和 重写 解释方法
  • 非终结符表达式类 封装 抽象表达式指针(实际上指向一个 终结符表达式对象 或 非终结符表达式对象) 和 重写 解释方法(形式上 调用 非终结符表达式类的 解释方法, 实际上 调用 终结符表达式类 或 非终结符表达式类的 解释方法(递归))
  • 上下文类 封装 上下文/变量和值的映射属性、设置 变量和值的映射方法 和 获取 变量 映射的 值方法
  • 创建过程:反向创建:先创建树叶,后创建树枝
  • 解释过程:正向解释:先解释树枝,后解释树叶(树状递归)

代码

#include <unordered_map>
#include <iostream>

using std::cout;
using std::endl;
using std::unordered_map;

// 抽象表达式类
class AbstractExpression
{
public:
    // 解释
    virtual int interpret(unordered_map<char, int> context_unmap) = 0;
};

// 终结符表达式类(树叶结点;用于将 变量 解释为 值)
class TerminalExpression : public AbstractExpression
{
public:
    TerminalExpression(char var) : var(var) {}

    // 解释
    int interpret(unordered_map<char, int> context_unmap) override
    {
        return context_unmap[this->var];
    }

private:
    // 变量
    char var;
};

// 非终结符表达式类(树枝结点;用于将 表达式 解释为 操作)
class NonTerminalExpression : public AbstractExpression
{
public:
    NonTerminalExpression(AbstractExpression *expr_1, AbstractExpression *expr_2) : expr_1(expr_1), expr_2(expr_2) {}

    // 解释
    int interpret(unordered_map<char, int> context_unmap) override // 形式上 调用 非终结符表达式类的 解释方法
    {
        // 这里 解释为 加法操作
        return expr_1->interpret(context_unmap) + expr_2->interpret(context_unmap); // 实际上 调用 终结符表达式类 或 非终结符表达式类的 解释方法(递归)
    }

private:
    // 抽象表达式指针(实际上指向一个 终结符表达式对象 或 非终结符表达式对象)
    AbstractExpression *expr_1;
    AbstractExpression *expr_2;
};

// 上下文类(用于 设置和获取 变量和值的映射)
class Context
{
public:
    Context() : context_unmap() {} // unordered_map<> 的默认构造方法 初始化

    // 设置 变量和值的映射
    void set_var_value(char var, int value)
    {
        this->context_unmap[var] = value;
    }

    // 获取 变量和值的映射
    unordered_map<char, int> get_var_value()
    {
        return this->context_unmap;
    }

private:
    // 上下文/变量和值的映射
    unordered_map<char, int> context_unmap;
};

// 客户端
int main()
{
    // 构建表达式:a + b
    AbstractExpression *expr_1 = new TerminalExpression('a'); // 抽象表达式指针(实际上指向一个终结符表达式对象)
    AbstractExpression *expr_2 = new TerminalExpression('b');
    AbstractExpression *expr_3 = new NonTerminalExpression(expr_1, expr_2); // 抽象表达式指针(实际上指向一个非终结符表达式对象)

    Context context; // 上下文对象
    // 设置 变量和值的映射
    context.set_var_value('a', 10);
    context.set_var_value('b', 20);

    //  获取 变量和值的映射
    unordered_map<char, int> context_unmap = context.get_var_value();

    // 解释
    int result = expr_3->interpret(context_unmap);
    cout << "Result: " << result << endl;
    // 创建过程:
    // 反向创建:先创建树叶,后创建树枝
    // 解释过程:
    // 正向解释:先解释树枝,后解释树叶(树状递归)

    delete expr_3;
    delete expr_2;
    delete expr_1;

    return 0;
}
/*
输出:
Result: 30
*/

总结

备忘录、迭代器和解释器模式(行为型设计模式)的 C++ 代码示例模板。


参考资料


作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

文章来源:https://blog.csdn.net/m0_62083249/article/details/135163140
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。