备忘录、迭代器和解释器模式(行为型设计模式)的 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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!