C++设计模式
资料https://blog.csdn.net/qq_52860170/article/details/142577985
软件的设计原则
目的:为了提高软件系统的可维护性、可复用性,增强软件的可扩展性、灵活性
开闭原则(OCP)
软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能。
对扩展开放,对修改关闭
实现:接口和抽象类
里氏替换原则(LSP)
任何基类可以出现的地方,子类一定可以出现,通俗来说,子类可以扩展父类的功能,但不能改变父类原有的功能
依赖倒置原则(DIP)
高层模块不应该依赖于低层模块,两者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象;对抽象编程,不对实现编程,降低了客户与实现模块间的耦合。
接口隔离原则(ISP)
客户端不应该被迫依赖于它不使用的方法;一个类对另一个类的依赖应该建立在最小的接口上。
单一职责原则(SRP)
一个类应该有且仅有一个职责
比如:手机:拍照、摄影、游戏、GPS
拆分成多个类:
拍摄职责:照相机、摄影机
游戏:PSP
GPS:专业GPS导航
高内聚、低耦合
创建型模式
简单工厂模式
只需要知道水果的名字则可得到相应的水果


角色:
Factory:工厂角色
Product:抽象产品角色
ConcreteProduct:具体产品角色
#include<iostream> using namespace std;
class Shape{ public: virtual void draw() const = 0; virtual ~Shape(){}; };
class Circle: public Shape{ public: void draw() const override{ cout<<"绘制圆形"<<endl; }
};
class Rectangle : public Shape{ public: void draw() const override{ cout<<"绘制矩形"<<endl; } };
class ShapeFactory { public: static Shape* createShape(const string& type){ if (type == "Circle") { return new Circle(); }else if(type == "Rectangle"){ return new Rectangle(); } throw invalid_argument("无效的形状类型!"); }
};
int main(){
try{ Shape* circle = ShapeFactory::createShape("Circle"); Shape* rectangle = ShapeFactory::createShape("Rectangle");
circle->draw(); rectangle->draw();
delete circle; delete rectangle;
Shape* unknown = ShapeFactory::createShape("Triangle");
}catch(const exception& e){ cout << e.what() << endl; } return 0; }
|
简单工厂模式虽然很好用,但是其违背了 开闭原则 当需要添加一个产品的时候,需要修改createShape部分的代码,因此便引入了工厂模式。
PPT之中一个例子

工厂模式

通过 将对象的实例化推迟到子类 来实现:每个具体工厂类只需要关注自己负责的产品创建,系统的扩展通过新增工厂-产品对实现,而不是修改现有代码。这种设计更符合面向对象的设计原则,特别适合需要支持多平台、多系列产品等场景。
抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建
抽象产品:定义了产品的规范,描述了产品的主要特性和功能
具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应
#include<iostream> using namespace std;
class Shape{ public: virtual void draw() const = 0; virtual ~Shape(){}; };
class Circle: public Shape{ public: void draw() const override{ cout<<"绘制圆形"<<endl; }
};
class Rectangle : public Shape{ public: void draw() const override{ cout<<"绘制矩形"<<endl; } };
class Triangle : public Shape{ public: void draw() const override{ cout<<"绘制三角形"<<endl; } };
class ShapeFactory { public: virtual Shape* createShape() const = 0; virtual ~ShapeFactory(){}; };
class CircleFactory: public ShapeFactory{ public: Shape* createShape() const override{ return new Circle(); } };
class RectangleFactory: public ShapeFactory{ public: Shape* createShape() const override{ return new Rectangle(); } };
class TriangleFactory: public ShapeFactory{ public: Shape* createShape() const override{ return new Triangle(); } };
int main(){
ShapeFactory* circleFactory = new CircleFactory(); Shape* circle = circleFactory->createShape(); ShapeFactory* rectangleFactory = new RectangleFactory(); Shape* rectangle = rectangleFactory->createShape();
circle->draw(); rectangle->draw();
ShapeFactory* triangleFactory = new TriangleFactory(); Shape* triangle = triangleFactory->createShape(); triangle->draw();
delete circle; delete rectangle; delete circleFactory; delete rectangleFactory;
delete triangle; delete triangleFactory;
return 0; }
|
抽象工程模式
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。
抽象工厂:提供了创建产品的接口,包含多个创建产品的方法,可以创建多个不同等级的产品
具体工厂:实现了抽象工厂中的多个抽象方法,完成具体产品的创建
抽象产品:定义了产品的规范,描述了产品的主要特征和功能,抽象工厂模式有多个抽象产品
具体产品:实现了抽象产品所定义的接口,由具体工厂来创建,它具体工厂是多对一关系

#include<iostream> #include <memory> using namespace std;
class Button{ public: virtual void render() const = 0; virtual ~Button() = default; };
class TextBox{ public: virtual void input(const string& text) const = 0; virtual ~TextBox() = default; };
class Switch{ public: virtual void toggle() const = 0; virtual ~Switch() = default; };
class ModernButton: public Button{ public: void render() const override { cout << "渲染现代风格按钮 [▣ Minimal]" << endl; } };
class ModernTextBox : public TextBox { public: void input(const string& text) const override { cout << "现代风格文本框输入: \"" << text << "\" (无边框)" << endl; } };
class ModernSwitch : public Switch { public: void toggle() const override { cout << "切换现代风格开关 ●━━━━●" << endl; } };
class RetroButton : public Button { public: void render() const override { cout << "渲染复古风格按钮 [▣ Beveled]" << endl; } };
class RetroTextBox : public TextBox { public: void input(const string& text) const override { cout << "复古风格文本框输入: \"" << text << "\" (像素字体)" << endl; } };
class RetroSwitch : public Switch { public: void toggle() const override { cout << "切换复古开关 ◈━━━◈" << endl; } };
class UIFactory{ public: virtual unique_ptr<Button> createButton() = 0; virtual unique_ptr<TextBox> createTextBox() = 0; virtual unique_ptr<Switch> createSwitch() = 0; virtual ~UIFactory() = default; };
class ModernUIFactory : public UIFactory { public: unique_ptr<Button> createButton() override { return make_unique<ModernButton>(); }
unique_ptr<TextBox> createTextBox() override { return make_unique<ModernTextBox>(); }
unique_ptr<Switch> createSwitch() override { return make_unique<ModernSwitch>(); } };
class RetroUIFactory : public UIFactory { public: unique_ptr<Button> createButton() override { return make_unique<RetroButton>(); }
unique_ptr<TextBox> createTextBox() override { return make_unique<RetroTextBox>(); }
unique_ptr<Switch> createSwitch() override { return make_unique<RetroSwitch>(); } };
void createUI(const unique_ptr<UIFactory>& factory) { auto button = factory->createButton(); auto textbox = factory->createTextBox(); auto switchCtrl = factory->createSwitch();
button->render(); textbox->input("Hello World"); switchCtrl->toggle(); }
int main(){
cout << "=== 现代风格 UI ===" << endl; createUI(make_unique<ModernUIFactory>());
cout << "\n=== 复古风格 UI ===" << endl; createUI(make_unique<RetroUIFactory>());
return 0; }
|
三种工厂模式对比表
特性 |
简单工厂模式 |
工厂方法模式 |
抽象工厂模式 |
创建目标 |
单一产品 |
单一产品 |
产品家族(多个关联产品) |
扩展维度 |
垂直扩展(产品类型) |
垂直扩展(产品类型) |
水平扩展(产品家族) |
开闭原则 |
违反 |
支持产品扩展 |
支持产品族扩展 |
工厂类数量 |
1个全能工厂 |
N个工厂对应N个产品 |
N个工厂对应N个产品族 |
适用场景 |
简单对象创建 |
单一产品扩展 |
多系列关联对象创建 |
单例模式
单例模式确保一个类只有一个实例,并提供一个全局访问点。

#include <iostream> using namespace std;
class Singleton { private: Singleton() = default; ~Singleton() = default; Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete;
public: static Singleton& getInstance() { static Singleton instance; return instance; }
void testFunction() { cout << "testFunction" << endl; } };
int main() { Singleton::getInstance().testFunction(); return 0; }
|
生成器(buider)模式
将一个复杂对象的构建与分离分开表示,使得同样的构建过程可以创建不同的表示
分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于: 某个对象的构建过程复杂的情况。
由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象,相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。
建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。
结构
抽象建造者类:这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体对象部件的创建。
具体建造者类:实现Builder接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
产品类:要创建的复杂对象
指挥者类:调用具体的建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建

#include<iostream> #include<string> using namespace std;
class Computer{ private: string m_cpu; string m_memory; string m_hardDisk; public: void setCPU(const string& cpu){ m_cpu = cpu;} void setMemory(const string& memory) { m_memory = memory; } void setHardDisk(const string& hardDisk) { m_hardDisk = hardDisk; }
void show() const { cout << "Computer Configuration:" << endl; cout << "CPU: " << m_cpu << endl; cout << "Memory: " << m_memory << endl; cout << "Hard Disk: " << m_hardDisk << endl; } };
class ComputerBuilder { public: virtual void buildCPU() = 0; virtual void buildMemory() = 0; virtual void buildHardDisk() = 0; virtual Computer* getResult() = 0; virtual ~ComputerBuilder() = default; };
class HighEndComputerBuilder : public ComputerBuilder { private: Computer* m_computer; public: HighEndComputerBuilder() : m_computer(new Computer()) {}
void buildCPU() override { m_computer->setCPU("Intel Core i9-12900K"); }
void buildMemory() override { m_computer->setMemory("64GB DDR5 4800MHz"); }
void buildHardDisk() override { m_computer->setHardDisk("2TB Samsung 980 Pro NVMe SSD"); }
Computer* getResult() override { return m_computer; }
~HighEndComputerBuilder() { delete m_computer; }
};
class OfficeComputerBuilder : public ComputerBuilder { private: Computer* m_computer;
public: OfficeComputerBuilder() : m_computer(new Computer()) {}
void buildCPU() override { m_computer->setCPU("Intel Core i5-12400"); }
void buildMemory() override { m_computer->setMemory("16GB DDR4 3200MHz"); }
void buildHardDisk() override { m_computer->setHardDisk("512GB Crucial P2 NVMe SSD"); }
Computer* getResult() override { return m_computer; }
~OfficeComputerBuilder() { delete m_computer; } };
class Director{ public: void construct(ComputerBuilder* builder){ builder->buildCPU(); builder->buildMemory(); builder->buildHardDisk(); } };
int main(){
Director director;
HighEndComputerBuilder highEndBuilder; director.construct(&highEndBuilder); Computer* gamingPC = highEndBuilder.getResult(); cout << "High-end Gaming PC:" << endl; gamingPC->show();
cout << "\n";
OfficeComputerBuilder officeBuilder; director.construct(&officeBuilder); Computer* officePC = officeBuilder.getResult(); cout << "Office PC:" << endl; officePC->show();
return 0; }
|
结构型模式
描述如何将类和对象按某种布局组成更大的结构
代理模式
为其他对象提供一种代理以控制对该对象的访问
远程(Remote)代理:为一个对象在不同地址空间提供局部代表
虚拟(Virtual)代理:在需要创建开销很大对象时缓存对象信息
保护(Protection)代理:控制对原始对象的访问
智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,例如记录访问的流量和次数等
结构:
抽象主题类:通过接口或抽象类声明真实主题和代理对象实现的业务方法
真实主题类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象
代理类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制、扩展真实主图的功能

样例:
如果对象是一个大图片,需要花费很长时间才能显示出来,此时需要做个图片Proxy来代替真正的图片
如果对象在某远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象
#include<iostream> #include<string> using namespace std;
class Image{ public: virtual void display() = 0; virtual ~Image() = default; };
class RealImage: public Image{ private: string filename; void loadFromDisk() { cout << "Loading image: " << filename << " from disk" << endl; } public: RealImage(const string& filename):filename(filename){ loadFromDisk(); };
void display() override { cout << "Displaying image: " << filename << endl; }
};
class ProxyImage :public Image{ private: RealImage* realImage = nullptr; string filename; bool accessAllowed = true;
bool checkAccess() const { return accessAllowed; }
void logAccess() { cout << "Logged access to image: " << filename << endl; } public: ProxyImage(const string& filename) : filename(filename) {}
void display() override { if (!checkAccess()) { std::cout << "Access denied for image: " << filename << std::endl; return; }
if (realImage == nullptr) { realImage = new RealImage(filename); } realImage->display(); logAccess(); }
~ProxyImage() { delete realImage; }
};
int main(){
Image* image1 = new ProxyImage("photo1.jpg"); Image* image2 = new ProxyImage("photo2.jpg");
image1->display();
image1->display();
image2->display();
delete image1; delete image2; return 0; }
|
适配器模式
将一个类的接口换成客户希望的另一个接口,使得原本由于接口不兼容而不能在一起工作那些类能一起工作
分类:
类适配器模式(耦合更高,应用较少)
对象适配器模式
结构:
目标接口:当前系统业务所期待的接口,它可以是抽象类或者接口
适配者类:它是被访问和适配的现存主件库中的组件接口
适配器类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按照目标接口的格式访问适配者
#include<iostream> using namespace std;
class Charger{ public: virtual void charge() const = 0; virtual ~Charger() = default; };
class EuroPlug{ public: void specificCharge() const { cout << "⚡ 使用欧洲插头充电 (220V)" << endl; } };
class EuroChargerAdapter : public Charger{ private: EuroPlug* euroPlug_; public: EuroChargerAdapter(EuroPlug* plug){ this->euroPlug_ = plug; }
void charge() const override { if(euroPlug_) { cout << "🔌 使用电源适配器转换" << endl; euroPlug_->specificCharge(); } }
};
int main() { EuroPlug euroPlug; Charger* charger = new EuroChargerAdapter(&euroPlug); charger->charge(); delete charger; return 0; }
|
装饰者模式
指在不改变现有对象结构的情况下,动态的给该对象增加一些职责(增加额外功能)的模式
例子:快餐店有炒面、炒饭这些快餐,可以额外附加鸡蛋、火腿、培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算总价就会显得比较麻烦。

#include<iostream> #include<string> using namespace std;
class Beverage { public: virtual double cost() const = 0; virtual string description() const = 0; virtual ~Beverage() = default; };
class Espresso: public Beverage { public: double cost() const override { return 1.99; } string description() const override{ return "Espresso"; } };
class CondimentDecorator : public Beverage { protected: Beverage* beverage; public: CondimentDecorator(Beverage* b) : beverage(b) {}; virtual ~CondimentDecorator(){ delete beverage; } };
class Mocha : public CondimentDecorator { public: Mocha(Beverage* b) : CondimentDecorator(b) {} double cost() const override { return beverage->cost() + 0.20; } string description() const override{ return beverage->description() + ", Mocha"; } };
class Milk : public CondimentDecorator { public: Milk(Beverage* b) : CondimentDecorator(b) {} double cost() const override { return beverage->cost() + 0.50; } string description() const override { return beverage->description() + ", Milk"; } };
int main(){ Beverage* espresso = new Espresso(); cout << espresso->description() << " $" << espresso->cost() << endl;
Beverage* espressoWithMocha = new Mocha(espresso); Beverage* espressoWithMochaMilk = new Milk(espressoWithMocha);
cout << espressoWithMochaMilk->description() << " $" << espressoWithMochaMilk->cost() << endl;
delete espressoWithMochaMilk; }
|
桥接模式
将抽象和实现分离,使它们可以独立变化。它是组合关系代替继承关系来实现的,从而降低了抽象和实现这两个可变维度的耦合度。

结构:
抽象化角色:定义抽象类,并包含一个对实现化角色的引用
扩展抽象化角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
实现化角色:定义实现化角色的接口,供扩展抽象化角色调用
具体实现化角色:给出实现化角色接口的具体实现

#include<iostream> #include<memory> #include<string> using namespace std;
class DrawAPI{ public: virtual void draw(const string& shape) = 0; virtual ~DrawAPI() = default; };
class OpenGLAPI:public DrawAPI{ public: void draw(const string& shape) override{ cout << "OpenGL绘制: "<<shape<< endl; } };
class DirectXAPI: public DrawAPI{ public: void draw(const string& shape) override{ cout << "DirectX绘制: "<<shape<< endl; } };
class Shape{ protected: unique_ptr<DrawAPI> drawAPI; public: Shape(DrawAPI * api):drawAPI(api){}; virtual void draw() = 0; virtual ~Shape() = default; };
class Circle:public Shape{ private: string myShape; public: Circle(string shape,DrawAPI * api):Shape(api),myShape(shape){}; void draw() override{ drawAPI->draw(this->myShape); } };
class Rectangle:public Shape{ private: string myShape; public: Rectangle(string shape,DrawAPI * api):Shape(api),myShape(shape){}; void draw() override{ drawAPI->draw(this->myShape); } };
int main(){
unique_ptr<Shape> circle = make_unique<Circle>("圆形", new OpenGLAPI()); unique_ptr<Shape> rect = make_unique<Rectangle>("矩形", new DirectXAPI()); circle->draw(); rect->draw();
Shape* openglRect = new Rectangle("矩形", new OpenGLAPI()); Shape* directxCircle = new Circle("圆形", new DirectXAPI()); openglRect->draw(); directxCircle->draw(); delete openglRect; delete directxCircle;
return 0; }
|
外观模式

结构:
#include<iostream> using namespace std;
class AudioDecoder{ public: void decodeAudio(const string& file){ cout << "解码音频: " << file << endl; } };
class VideoDecoder { public: void decodeVideo(const string& file){ cout << "解码视频: " << file << endl; } };
class FileLoader { public: string load(const string& path){ cout << "加载文件: " << path << endl; return path.substr(path.find_last_of("/") + 1); } };
class PlaybackManager{ private: FileLoader fileLoader; AudioDecoder audioDecoder; VideoDecoder videoDecoder;
public: void play(const string& filePath) { string fileName = fileLoader.load(filePath); audioDecoder.decodeAudio(fileName); videoDecoder.decodeVideo(fileName); cout << "开始播放 " << fileName << endl; }
};
int main() { PlaybackManager player; player.play("/media/movie.mp4"); return 0; }
|
组合模式
部分整体模式,是用于把一组相似的对象当做一个单一的对象,组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,她创建了对象组的树形结构。

结构:
抽象根节点:定义系统各层次对象共有方法和属性,可以预先定义一些默认行为和属性
树枝节点:定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构
叶子节点:叶子节点对象,其下再无分支,是系统层次遍历的最小单位
#include <iostream> #include <vector> #include <memory> #include <string> #include <algorithm> using namespace std;
class FileSystemComponent{ public: virtual void display(int depth = 0) const = 0; virtual size_t getSize() const = 0; virtual ~FileSystemComponent() = default; };
class File : public FileSystemComponent { private: string name_; size_t size_; public: File(const string& name,size_t size):name_(name),size_(size){}
void display(int depth = 0) const override{ cout << string(depth, '\t') << "📄 " << name_ << " (" << size_ << " bytes)" << endl; }
size_t getSize() const override { return size_; } };
class Directory:public FileSystemComponent{ private: string name_; vector<shared_ptr<FileSystemComponent>> children_; public: Directory(const string& name) : name_(name) {}
void addComponent(shared_ptr<FileSystemComponent> component){ children_.push_back(component); }
void removeComponent(shared_ptr<FileSystemComponent> component){ children_.erase( remove(children_.begin(), children_.end(), component), children_.end() ); }
void display(int depth = 0) const override { cout << string(depth, '\t') << "📁 " << name_ << " [" << getSize() << " bytes]" << endl;
for (const auto& child : children_) { child->display(depth + 1); } }
size_t getSize() const override { size_t total = 0; for (const auto& child : children_) { total += child->getSize(); } return total; } };
int main(){ auto file1 = make_shared<File>("document.txt", 1500); auto file2 = make_shared<File>("image.jpg", 2500); auto file3 = make_shared<File>("notes.md", 800);
auto subdir = make_shared<Directory>("Downloads"); subdir->addComponent(file2); subdir->addComponent(file3);
auto root = make_shared<Directory>("Root"); root->addComponent(file1); root->addComponent(subdir);
root->addComponent(make_shared<File>("backup.zip", 4200));
cout << "File System Structure:\n"; root->display();
cout << "\nTotal size of root: " << root->getSize() << " bytes" << endl;
return 0; }
|
享元模式
运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率。
内部状态。不会随着环境的改变而改变的可共享部分
外部状态。随着环境的改变而改变的不可共享的部分。享元模式的实现要领就是区分应用中的这两种状态,并将外部状态外部化。
引例:

#include<iostream> #include <string> #include <unordered_map> #include <vector> using namespace std;
class TreeType { private: string name_; string color_; string texture_; public: TreeType(const string& name, const string& color, const string& texture) : name_(name), color_(color), texture_(texture) {} void draw(int x, int y, int age) const { cout << "绘制 " << name_ << " 在 (" << x << ", " << y << "),颜色:" << color_ << ",纹理:" << texture_ << ",年龄:" << age << "年\n"; } };
class TreeFactory { private: unordered_map<string,TreeType> treeTypes_; string makeKey(const string& name, const string& color, const string& texture) { return name + "_" + color + "_" + texture; } public: const TreeType& getTreeType(const string& name, const string& color, const string& texture) { string key = makeKey(name, color, texture); if (treeTypes_.find(key) == treeTypes_.end()) { cout << "创建新的树木类型: " << key << endl; treeTypes_.emplace(key, TreeType(name, color, texture)); } return treeTypes_.at(key); } };
class Tree { private: int x_; int y_; int age_; const TreeType& type_;
public: Tree(int x, int y, int age, const TreeType& type) : x_(x), y_(y), age_(age), type_(type) {}
void draw() const { type_.draw(x_, y_, age_); } };
class Forest { private: vector<Tree> trees_; TreeFactory factory_;
public: void plantTree(int x, int y, int age, const string& name, const string& color, const string& texture) { const TreeType& type = factory_.getTreeType(name, color, texture); trees_.emplace_back(x, y, age, type); }
void draw() const { for (const auto& tree : trees_) { tree.draw(); } } };
int main() { Forest forest; forest.plantTree(1, 2, 5, "松树", "深绿", "针叶纹理"); forest.plantTree(3, 4, 7, "橡树", "浅绿", "宽叶纹理"); forest.plantTree(5, 6, 3, "松树", "深绿", "针叶纹理"); forest.plantTree(7, 8, 2, "白桦", "白色", "条纹纹理"); forest.plantTree(9, 0, 4, "橡树", "浅绿", "宽叶纹理");
cout << "\n开始绘制森林:\n"; forest.draw();
return 0; }
|
行为型模式
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法完成的任务,涉及算法与对象之间职责的分配
模板方法模式

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变算法结构的情况下重定义该算法的某些特定步骤
#include<iostream> using namespace std;
class Beverage{ public: virtual void prepareBeverage() final { boilWater(); brew(); pourInCup(); if (customerWantsCondiments()) { addCondiments(); } } protected: void boilWater() { cout << "Boiling water" << endl; }
void pourInCup() { cout << "Pouring into cup" << endl; }
virtual void brew() = 0; virtual void addCondiments() = 0;
virtual bool customerWantsCondiments() { return true; } };
class Coffee:public Beverage{ protected: void brew() override { std::cout << "Brewing coffee grounds" << std::endl; }
void addCondiments() override { std::cout << "Adding sugar and milk" << std::endl; }
bool customerWantsCondiments() override { char choice; std::cout << "Would you like milk and sugar with your coffee? (y/n) "; std::cin >> choice; return choice == 'y' || choice == 'Y'; } };
class Tea : public Beverage { protected: void brew() override { std::cout << "Steeping the tea" << std::endl; }
void addCondiments() override { std::cout << "Adding lemon" << std::endl; }
};
int main() { std::cout << "Making coffee:" << std::endl; Coffee coffee; coffee.prepareBeverage();
std::cout << "\nMaking tea:" << std::endl; Tea tea; tea.prepareBeverage();
return 0; }
|
策略模式
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响到使用算法的用户,策略模式属于对象行为模式,通过对算法进行封装,把使用算法的责任和算法是实现分割开来,并委派给不同对象对这些算法进行管理
结构:
策略模式引例

#include<iostream> #include <memory> using namespace std;
class PaymentStrategy{ public: virtual void pay(double amount) const = 0; virtual ~PaymentStrategy() = default; };
class CreditCardPayment:public PaymentStrategy{ void pay(double amount) const override{ cout << "使用信用卡支付:" << amount << "元" <<endl;; } };
class AlipayPayment:public PaymentStrategy{ public: void pay(double amount) const override{ cout << "使用支付宝支付:" << amount << "元" <<endl; } };
class WeChatPayment:public PaymentStrategy{ public: void pay(double amount) const override{ cout << "使用微信支付:" << amount << "元" <<endl; } };
class Order{ private: unique_ptr<PaymentStrategy> thisPaymentStrategy; public: void setPaymentStrategy(unique_ptr<PaymentStrategy> strategy){ thisPaymentStrategy = move(strategy); }
void checkout(double amount){ if (thisPaymentStrategy) { thisPaymentStrategy->pay(amount); } else { std::cout << "错误:未选择支付方式!\n"; } }
};
int main(){
Order order;
order.setPaymentStrategy(make_unique<CreditCardPayment>()); order.checkout(100.50); order.setPaymentStrategy(std::make_unique<AlipayPayment>()); order.checkout(200.0); order.setPaymentStrategy(std::make_unique<WeChatPayment>()); order.checkout(50.0);
return 0; }
|
命令模式
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分隔开,这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储、传递、调用、增加和管理
结构:
抽象命令类角色:定义命令的接口,声明执行的方法
具体命令角色:具体的命令,实现命令接口;通常会持有接受者,并调用接受者的功能来完成命令要执行的操作
实现者/接受者角色:接受者,真正执行命令的对象,任何类都可成为一个接收者,只要它能够实现命令要求实现的相应的功能
调用者/请求者角色:要求命令对象执行请求,通常会持有命令对象,可以持有很多命令对象
引例:

简单的:遥控器,集成很多的命令
#include<iostream> using namespace std;
class Appliance { public: virtual void on() = 0; virtual void off() = 0; virtual ~Appliance() = default; };
class Light:public Appliance{ public: void on() override{ cout<<"电灯打开了"<<endl; } void off() override{ cout<<"电灯关闭了"<<endl; } };
class Fan:public Appliance{ public: void on() override{ cout<<"风扇打开了"<<endl; } void off() override{ cout<<"风扇关闭了"<<endl; } };
class Command{ public: virtual void execute() = 0; virtual void undo() = 0; virtual ~Command() = default; };
class TurnOnCommand:public Command{ private: Appliance* appliance; public: TurnOnCommand(Appliance* app) : appliance(app) {} void execute() override { appliance->on(); } void undo() override { appliance->off(); } };
class TurnOffCommand : public Command { Appliance* appliance; public: TurnOffCommand(Appliance* app) : appliance(app) {} void execute() override { appliance->off(); } void undo() override { appliance->on(); } };
class RemoteControl{ private: Command * command; Command* lastCommand; public: void setCommand(Command* cmd) { command = cmd; }
void pressButton() { command->execute(); lastCommand = command; }
void pressUndo() { if(lastCommand) { lastCommand->undo(); lastCommand = nullptr; } }
};
int main(){
Light livingRoomLight; Fan bathroomFan;
TurnOnCommand lightOn(&livingRoomLight); TurnOffCommand fanOff(&bathroomFan);
RemoteControl remote; remote.setCommand(&lightOn); remote.pressButton(); remote.pressUndo();
remote.setCommand(&fanOff); remote.pressButton(); remote.pressUndo();
return 0; }
|
责任链模式
又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

#include<iostream> using namespace std;
class PurchaseRequest{ public: int type; int id; double amount; PurchaseRequest(int t, int i, double a) : type(t), id(i), amount(a) {} };
class Approver{ protected: Approver * successor; string name; public: Approver(string n) : name(n), successor(nullptr) {} void setSuccessor(Approver* s) { successor = s; } virtual void processRequest(PurchaseRequest* request) = 0; };
class Manager :public Approver{ public: Manager(string n) : Approver(n) {};
void processRequest(PurchaseRequest* request){ if(request->amount<5000){ cout << name << "经理审批采购单#" << request->id << ",金额:" << request->amount << "元" << endl; }else if (successor != nullptr) { successor->processRequest(request); } } };
class Director : public Approver { public: Director(string n) : Approver(n) {} void processRequest(PurchaseRequest* request) override { if (request->amount < 10000) { cout << name << "总监审批采购单#" << request->id << ",金额:" << request->amount << "元" << endl; } else if (successor != nullptr) { successor->processRequest(request); } } };
class CEO : public Approver { public: CEO(string n) : Approver(n) {} void processRequest(PurchaseRequest* request) override { cout << name << "CEO审批采购单#" << request->id << ",金额:" << request->amount << "元" << endl; } };
int main(){
Manager manager("张"); Director director("王"); CEO ceo("李");
manager.setSuccessor(&director); director.setSuccessor(&ceo);
PurchaseRequest req1(1, 1001, 4500); PurchaseRequest req2(2, 1002, 8000); PurchaseRequest req3(3, 1003, 150000);
manager.processRequest(&req1); manager.processRequest(&req2); manager.processRequest(&req3);
return 0; }
|
状态模式
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为
结构:

#include <iostream> #include <memory> using namespace std;
class ElevatorContext;
class ElevatorState { public: virtual void openDoors(ElevatorContext* context) = 0; virtual void closeDoors(ElevatorContext* context) = 0; virtual void move(ElevatorContext* context) = 0; virtual void stop(ElevatorContext* context) = 0; virtual ~ElevatorState() = default; };
class DoorsOpenState; class DoorsClosedState; class MovingState;
class ElevatorContext { private: unique_ptr<ElevatorState> currentState;
public: ElevatorContext(unique_ptr<ElevatorState> state); void requestOpenDoors(); void requestCloseDoors(); void requestMove(); void requestStop();
void changeState(unique_ptr<ElevatorState> state); void displayState(const string& stateName); };
class DoorsOpenState : public ElevatorState { public: void openDoors(ElevatorContext* context) override; void closeDoors(ElevatorContext* context) override; void move(ElevatorContext* context) override; void stop(ElevatorContext* context) override; };
class DoorsClosedState : public ElevatorState { public: void openDoors(ElevatorContext* context) override; void closeDoors(ElevatorContext* context) override; void move(ElevatorContext* context) override; void stop(ElevatorContext* context) override; };
class MovingState : public ElevatorState { public: void openDoors(ElevatorContext* context) override; void closeDoors(ElevatorContext* context) override; void move(ElevatorContext* context) override; void stop(ElevatorContext* context) override; };
ElevatorContext::ElevatorContext(unique_ptr<ElevatorState> state) : currentState(move(state)) {}
void ElevatorContext::requestOpenDoors() { currentState->openDoors(this); } void ElevatorContext::requestCloseDoors() { currentState->closeDoors(this); } void ElevatorContext::requestMove() { currentState->move(this); } void ElevatorContext::requestStop() { currentState->stop(this); }
void ElevatorContext::changeState(unique_ptr<ElevatorState> state) { currentState = move(state); }
void ElevatorContext::displayState(const string& stateName) { cout << "Elevator is now in [" << stateName << "] state\n"; }
void DoorsOpenState::openDoors(ElevatorContext* context) { cout << "Doors are already open\n"; }
void DoorsOpenState::closeDoors(ElevatorContext* context) { cout << "Closing doors...\n"; context->changeState(make_unique<DoorsClosedState>()); context->displayState("Doors Closed"); }
void DoorsOpenState::move(ElevatorContext* context) { cout << "Cannot move while doors are open\n"; }
void DoorsOpenState::stop(ElevatorContext* context) { cout << "Already stopped with open doors\n"; }
void DoorsClosedState::openDoors(ElevatorContext* context) { cout << "Opening doors...\n"; context->changeState(make_unique<DoorsOpenState>()); context->displayState("Doors Open"); }
void DoorsClosedState::closeDoors(ElevatorContext* context) { cout << "Doors are already closed\n"; }
void DoorsClosedState::move(ElevatorContext* context) { cout << "Starting movement...\n"; context->changeState(make_unique<MovingState>()); context->displayState("Moving"); }
void DoorsClosedState::stop(ElevatorContext* context) { cout << "Already stopped with closed doors\n"; }
void MovingState::openDoors(ElevatorContext* context) { cout << "Cannot open doors while moving\n"; }
void MovingState::closeDoors(ElevatorContext* context) { cout << "Doors are already closed\n"; }
void MovingState::move(ElevatorContext* context) { cout << "Already moving\n"; }
void MovingState::stop(ElevatorContext* context) { cout << "Stopping...\n"; context->changeState(make_unique<DoorsClosedState>()); context->displayState("Doors Closed"); }
int main() { ElevatorContext elevator(make_unique<DoorsOpenState>()); elevator.requestCloseDoors(); elevator.requestMove(); elevator.requestOpenDoors(); elevator.requestStop(); elevator.requestOpenDoors();
return 0; }
|
观察者模式
又称为发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时检测某一主题对象,这个主题对象在状态变化时,会通知所有的观察者对象,使它们能够自动更新自己
结构:
抽象主题(抽象被观察者),抽象主题角色吧所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象
具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态

#include<iostream> #include<vector> #include<algorithm> using namespace std;
class Subject;
class Observer{ public: virtual void update(Subject* subject) = 0; virtual ~Observer() = default; };
class Subject{ private: vector<Observer*> observers_; public: virtual ~Subject() = default; virtual void attach(Observer* observer) { observers_.push_back(observer); } virtual void detach(Observer* observer){ observers_.erase(remove(observers_.begin(),observers_.end(),observer), observers_.end()); } virtual void notifyObservers() { for(auto observer: observers_){ observer->update(this); } } };
class WeatherStation : public Subject { private: float temperature_; float humidity_; float pressure_; public: void setMeasurements(float temperature, float humidity, float pressure) { temperature_ = temperature; humidity_ = humidity; pressure_ = pressure; notifyObservers(); }
float getTemperature() const { return temperature_; } float getHumidity() const { return humidity_; } float getPressure() const { return pressure_; } };
class CurrentConditionsDisplay : public Observer { private: WeatherStation* weatherStation_; float temperature_; float humidity_; public: CurrentConditionsDisplay(WeatherStation* weatherStation) : weatherStation_(weatherStation) { weatherStation_->attach(this); } void update(Subject* subject) override { if (auto ws = dynamic_cast<WeatherStation*>(subject)) { temperature_ = ws->getTemperature(); humidity_ = ws->getHumidity(); display(); } } void display() const { cout << "Current conditions: " << temperature_ << "°C and " << humidity_ << "humidity\n"; }
};
class ForecastDisplay : public Observer { public: explicit ForecastDisplay(WeatherStation* weatherStation) : weatherStation_(weatherStation) { weatherStation_->attach(this); }
void update(Subject* subject) override { if (auto ws = dynamic_cast<WeatherStation*>(subject)) { lastPressure_ = currentPressure_; currentPressure_ = ws->getPressure(); display(); } }
void display() const { cout << "Forecast: "; if (currentPressure_ > lastPressure_) { cout << "Improving weather!\n"; } else if (currentPressure_ == lastPressure_) { cout << "More of the same\n"; } else { cout << "Watch out for cooler, rainy weather\n"; } }
private: WeatherStation* weatherStation_; float currentPressure_ = 1013.0f; float lastPressure_ = 1013.0f; };
int main() { WeatherStation weatherStation; CurrentConditionsDisplay currentDisplay(&weatherStation); ForecastDisplay forecastDisplay(&weatherStation);
weatherStation.setMeasurements(25.0f, 65.0f, 1015.0f); weatherStation.setMeasurements(22.5f, 70.0f, 1012.0f); weatherStation.setMeasurements(20.0f, 90.0f, 1008.0f);
return 0; }
#include <iostream> #include <vector>
class Observer { public: virtual void update(float temperature) = 0; virtual ~Observer() = default(); };
class TemperatureSensor { std::vector<Observer*> observers_; float temperature_;
public: void attach(Observer* observer) { observers_.push_back(observer); }
void setTemperature(float newTemp) { temperature_ = newTemp; notifyObservers(); }
private: void notifyObservers() { for (auto observer : observers_) { observer->update(temperature_); } } };
class Display : public Observer { public: void update(float temperature) override { std::cout << "温度更新: " << temperature << "°C\n"; } };
int main() { TemperatureSensor sensor; Display display;
sensor.attach(&display);
sensor.setTemperature(25.5); sensor.setTemperature(23.0); sensor.setTemperature(20.5);
return 0; }
|
中介者模式
又叫调停模式。定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立的改变他们之间的交互
结构:
抽象中介者:中介者的借口,提供了同事对象注册与转发同事对象信息的抽象方法
具体中介:实现中介者借口,定义一个List集合来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色
抽象同事类:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能
具体同事类:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互
#include<iostream> #include<string> #include <vector> using namespace std;
class Colleague;
class Mediator { public: virtual void sendMessage(const string& message,const Colleague* sender) = 0; virtual void addColleague(Colleague* colleague) = 0; virtual ~Mediator() = default; };
class Colleague{ protected: Mediator* mediator_; string name_; public: Colleague(Mediator* mediator, const string& name) : mediator_(mediator), name_(name) {}
virtual void send(const string& message) = 0; virtual void receive(const string& message) = 0; virtual ~Colleague() = default; string getName() const { return name_; } };
class ChatRoomMediator:public Mediator{ private: vector<Colleague*> colleagues_; public: void addColleague(Colleague* colleague) override { colleagues_.push_back(colleague); }
void sendMessage(const string& message, const Colleague* sender) override { for (auto colleague : colleagues_) { if (colleague != sender) { colleague->receive(message); } } } };
class User: public Colleague{ public: User(Mediator* mediator, const string& name) : Colleague(mediator, name) { mediator_->addColleague(this); }
void send(const string& message) override { cout << name_ << " 发送消息: " << message << endl; mediator_->sendMessage(message, this); }
void receive(const string& message) override { cout << name_ << " 收到消息: " << message << endl; } };
int main() { ChatRoomMediator chatRoom;
User alice(&chatRoom, "Alice"); User bob(&chatRoom, "Bob"); User charlie(&chatRoom, "Charlie");
alice.send("大家好!"); cout << endl; bob.send("今天天气不错!"); cout << endl; charlie.send("有人想去喝咖啡吗?");
return 0; }
|
迭代器模式
提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示
结构:
抽象聚合对象:定义存储、添加、删除聚合元素以及创建迭代器对象的接口
具体聚合对象:实现抽象聚合类,返回一个具有迭代器的实例
抽象迭代器对象:定义访问和遍历聚合元素的接口,通常包含hasNext()、next()等方法
具体迭代器对象:实现抽象迭代器接口所定义的方法,完成对聚合对象的遍历,记录遍历当前位置
将遍历的功能分开,专门使用一个类来管理

#include<iostream> #include<string> using namespace std;
class StringCollection;
class Iterator{ public: virtual string next() = 0; virtual bool hasNext() const = 0; virtual ~Iterator() = default; };
class Collection { public: virtual ~Collection() = default; virtual Iterator* createIterator() const = 0; };
class StringIterator : public Iterator { private: const StringCollection& collection; size_t currentIndex; public: StringIterator(const StringCollection& coll); string next() override; bool hasNext() const override; };
class StringCollection : public Collection { private: string items[5]; size_t count = 0;
public: void add(const string& item) { if (count < 5) { items[count++] = item; } }
size_t size() const { return count; } string get(size_t index) const { return items[index]; }
Iterator* createIterator() const override { return new StringIterator(*this); } };
StringIterator::StringIterator(const StringCollection& coll) : collection(coll), currentIndex(0) {}
string StringIterator::next() { return collection.get(currentIndex++); }
bool StringIterator::hasNext() const { return currentIndex < collection.size(); }
int main(){
StringCollection collection; collection.add("First"); collection.add("Second"); collection.add("Third");
Iterator* it = collection.createIterator(); while (it->hasNext()) { cout << it->next() << endl; }
delete it; return 0; }
|
访问者模式
封装一些作用于某些数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作
结构:
抽象访问者:定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素类个数是一样的,从这点不难看出,访问者模式要求元素的个数不能改变
具体访问者:给出对每一个元素类访问时所产生的具体行为
抽象元素:定义了一个接受访问者的方法,每一个元素都要可以被访问者访问
具体元素:提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用范文哲提供的访问该元素类的方法
对象结构角色:定义当中所提到的对象结构,对象结构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特征的类,它会含有一组元素,并且可以迭代这些元素,供访问者访问

#include<iostream> #include<vector> using namespace std;
class ConcreteElementA; class ConcreteElementB;
class Visitor { public: virtual void visit(ConcreteElementA* element) = 0; virtual void visit(ConcreteElementB* element) = 0; virtual ~Visitor() {} };
class Element { public: virtual void accept(Visitor* visitor) = 0; virtual ~Element() {} };
class ConcreteElementA : public Element { public: void accept(Visitor* visitor) override { visitor->visit(this); } string operationA() { return "具体元素A的操作"; } };
class ConcreteElementB : public Element { public: void accept(Visitor* visitor) override { visitor->visit(this); } string operationB() { return "具体元素B的操作"; } };
class ConcreteVisitor : public Visitor { public: void visit(ConcreteElementA* element) override { cout << "访问者正在访问 " << element->operationA() << endl; } void visit(ConcreteElementB* element) override { cout << "访问者正在访问 " << element->operationB() << endl; } };
class ObjectStructure { private: vector<Element*> elements; public: void add(Element* element) { elements.push_back(element); } void accept(Visitor* visitor) { for (auto elem : elements) { elem->accept(visitor); } } }; int main(){
ObjectStructure structure; structure.add(new ConcreteElementA()); structure.add(new ConcreteElementB()); ConcreteVisitor visitor; structure.accept(&visitor);
return 0; }
|
备忘录模式
又叫快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态
结构:
发起人角色:记录当前时刻的内部状态信息,提供创建备忘录和回复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
备忘录角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人
管理者角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问和修改

#include <iostream> #include <string> #include <vector> using namespace std;
class TextMemento{ private: string text_; public: TextMemento(string text) : text_(move(text)) {} string GetText() const { return text_; } void SetText(const string& text) { text_ = text; } };
class TextEditor { private: string content_; public: void Write(const string& text) { content_ += text; } TextMemento CreateMemento() const { return TextMemento(content_); } void RestoreMemento(const TextMemento& memento) { content_ = memento.GetText(); } void Show() const { cout << "Current content: " << content_ << "\n"; } };
class History { private: vector<TextMemento> history_; public: void Save(const TextMemento& memento) { history_.push_back(memento); } TextMemento Undo() { if (!history_.empty()) { return history_.back(); } return TextMemento(""); } };
int main(){
TextEditor editor; History history; editor.Write("Hello"); history.Save(editor.CreateMemento()); editor.Show(); editor.Write(" World"); editor.Show(); editor.RestoreMemento(history.Undo()); editor.Show();
return 0; }
#include <iostream> #include <string> #include <vector>
class IMemento { public: virtual ~IMemento() = default; };
class TextEditor { private: std::string content_; public: class TextMemento : public IMemento { public: TextMemento(std::string text) : text_(std::move(text)) {} friend class TextEditor; private: std::string text_; };
void Write(const std::string& text) { content_ += text; }
IMemento* CreateMemento() const { return new TextMemento(content_); }
void RestoreMemento(const IMemento* memento) { auto concrete = dynamic_cast<const TextMemento*>(memento); if (concrete) { content_ = concrete->text_; } }
void Show() const { std::cout << "Current content: " << content_ << "\n"; }
};
class History { private: std::vector<IMemento*> history_; public: void Save(IMemento* memento) { history_.emplace_back(memento); } IMemento* Undo() { if (!history_.empty()) { return history_.back(); } return nullptr; } };
int main() { TextEditor editor; History history; editor.Write("Hello"); history.Save(editor.CreateMemento()); editor.Show(); editor.Write(" World"); editor.Show(); editor.RestoreMemento(history.Undo()); editor.Show(); }
|
白盒实现:
黑盒实现:
解释器模式
给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
结构:
抽象表达式角色: 定义解释器的接口,约定解释器的解释操作,主要包含解释方法interpret
终结符表达式角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之对应
非终结符表达式角色:也是抽象表达式的子类。是来实现文法中与非终结符相关的操作,文法中发每条规则都对应于一个非终结符表达式
环境角色:通常包含各个解释器需要的数据或者是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值
客户端:主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法
#include <iostream> #include <memory> #include <unordered_map> using namespace std;
class Context { private: unordered_map<string, int> variables;
public: void setVariable(const string& var, int value) { variables[var] = value; }
int getVariable(const string& var) const { return variables.at(var); } };
class Expression { public: virtual ~Expression() = default; virtual int interpret(const Context& context) = 0; };
class VariableExpression : public Expression { private: string varName;
public: explicit VariableExpression(string var) : varName(move(var)) {}
int interpret(const Context& context) override { return context.getVariable(varName); } };
class NumberExpression : public Expression { private: int number;
public: explicit NumberExpression(int num) : number(num) {}
int interpret(const Context& context) override { return number; } };
class AddExpression : public Expression { private: unique_ptr<Expression> left; unique_ptr<Expression> right;
public: AddExpression(unique_ptr<Expression> l, unique_ptr<Expression> r) : left(move(l)), right(move(r)) {}
int interpret(const Context& context) override { return left->interpret(context) + right->interpret(context); } };
class SubtractExpression : public Expression { private: unique_ptr<Expression> left; unique_ptr<Expression> right;
public: SubtractExpression(unique_ptr<Expression> l, unique_ptr<Expression> r) : left(move(l)), right(move(r)) {}
int interpret(const Context& context) override { return left->interpret(context) - right->interpret(context); } };
int main() { Context context; context.setVariable("x", 10); context.setVariable("y", 5);
auto expr = make_unique<SubtractExpression>( make_unique<AddExpression>( make_unique<VariableExpression>("x"), make_unique<NumberExpression>(20) ), make_unique<AddExpression>( make_unique<VariableExpression>("y"), make_unique<NumberExpression>(5) ) );
int result = expr->interpret(context); cout << "计算结果: " << result << endl;
return 0; }
|