首页 > 系统相关 >Linux C++ 066-设计模式之访问者模式

Linux C++ 066-设计模式之访问者模式

时间:2024-07-20 22:27:51浏览次数:17  
标签:066 void visit C++ class 设计模式 public cpv 访问者

Linux C++ 066-设计模式之访问者模式

本节关键字:Linux、C++、设计模式、访问者模式
相关库函数:

概念

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

访问者模式旨在将数据结构与在该数据结构上执行的操作分离,从而使得添加新的操作变得更容易,而无需修改数据结构本身。解决在稳定数据结构和易变操作之间的耦合问题,使得操作可以独立于数据结构变化。

优缺点

优点

单一职责原则:访问者模式符合单一职责原则,每个类只负责一项职责。
扩展性:容易为数据结构添加新的操作。
灵活性:访问者可以独立于数据结构变化。

缺点

违反迪米特原则:元素需要向访问者公开其内部信息。
元素类难以变更:元素类需要维持与访问者的兼容。
依赖具体类:访问者模式依赖于具体类而不是接口,违反了依赖倒置原则。

使用场景

访问者模式可以用于功能统一,如报表生成、用户界面显示、拦截器和过滤器等。

当需要对一个对象结构中的对象执行多种不同的且不相关的操作时,尤其是这些操作需要避免"污染"对象类本身。

当对象结构稳定,但需要在其上定义多种新操作时,考虑使用访问者模式。
当需要避免操作"污染"对象类时,使用访问者模式封装操作。

角色说明

Visitor 抽象访问者角色:为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。

ConcreteVisitor.具体访问者角色:实现Visitor声明的接口。

Element 定义一个接受访问操作(accept()):它以一个访问者(Visitor)作为参数。

ConcreteElement 具体元素:实现了抽象元素(Element)所定义的接受操作接口。

ObjectStructure 结构对象角色:这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

Client 客户端(可选):使用访问者模式对对象结构进行操作。

示例代码

#include <iostream>
#include <vector>
using namespace std;

class Computer;
class Mouse;
class Keyboard;
class Monitor;
class ComputerPartVisitor 
{
public:
    ComputerPartVisitor() { }
	virtual void visit(Computer *computer) { }
	virtual void visit(Mouse *mouse) { }
    virtual void visit(Keyboard *keyboard) { }
    virtual void visit(Monitor *monitor) { }
};
class ComputerPart
{
public:
	ComputerPart() { }
	virtual void accept(ComputerPartVisitor *cpv) { }
};
class Keyboard : public ComputerPart 
{
public:
	Keyboard() { }
	void accept(ComputerPartVisitor *cpv) {
		cpv->visit(this);
	}
};
class Monitor : public ComputerPart 
{
public:
	void accept(ComputerPartVisitor *cpv) {
		cpv->visit(this);
	}
};
class Mouse : public ComputerPart 
{
public:
	void accept(ComputerPartVisitor *cpv) {
		cpv->visit(this);
	}
};
class Computer : public ComputerPart 
{
public: 
	Computer() {
		m_Parts.push_back(new Mouse());
		m_Parts.push_back(new Keyboard());
		m_Parts.push_back(new Monitor());
	}
	void accept(ComputerPartVisitor *cpv) {
		for (int i = 0; i < m_Parts.size(); i++) {
			m_Parts[i]->accept(cpv);
		}
		cpv->visit(this);
	}
private:
	vector<ComputerPart*>	m_Parts;
};
class ComputerPartDisplayVisitor : public ComputerPartVisitor 
{
public:
	void visit(Computer *computer) {
		cout << "Displaying Computer." << endl;
	}
	void visit(Mouse *mouse) {
		cout << "Displaying Mouse." << endl;
	} 
	void visit(Keyboard *keyboard) {
		cout << "Displaying Keyboard." << endl;
	}
	void visit(Monitor *monitor) {
		cout << "Displaying Monitor." << endl;
	}
};
int main(int argc, char *argv[])
{
	ComputerPart *computer = new Computer();
	computer->accept(new ComputerPartDisplayVisitor());
	
	return 0;
}
/*
Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.
*/

标签:066,void,visit,C++,class,设计模式,public,cpv,访问者
From: https://blog.csdn.net/qq_45157350/article/details/139953827

相关文章

  • C++面向对象编程的一个核心概念--RAII
    RAII是"ResourceAcquisitionIsInitialization"(资源获取即初始化)的缩写,它是C++编程中的一种编程技术,用于管理资源的生命周期。RAII是C++面向对象编程的一个核心概念,它利用对象的构造函数和析构函数来自动管理资源,如内存、文件句柄、线程、互斥锁等。RAII的主要原则包括:1.*......
  • 如何使用C++中的字符串类(如std::string)
    在C++中,std::string 类是标准模板库(StandardTemplateLibrary,STL)的一部分,它提供了对字符串的灵活处理。std::string 使得字符串的存储、操作、比较、查找等任务变得更加方便和高效。下面将介绍如何使用 std::string 类。1.包含头文件要使用 std::string,首先需要包含......
  • 掌握 C++ 异常艺术:构建健壮程序的秘诀与实战策略「一」
    以下内容为本人的烂笔头,如需要转载,请全文无改动地复制粘贴,原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/WC8CThJ77oHMsCSH0CBzsQ在过去几十年的编程历史中,异常处理的演变仿佛一场文明的进化史,它不仅仅是技术的革新,更是编程思想与哲学的深刻体现。从古早的错......
  • Android C++系列:Linux文件系统(二)
    1.VFS虚拟文件系统Linux支持各种各样的文件系统格式,如ext2、ext3、reiserfs、FAT、NTFS、iso9660等等,不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式,然而这些文件系统都可以mount到某个目录下,使我们看到一个统一的目录树,各种文件系统上的目录和文件我们用l......
  • Android C++系列:函数返回值注意事项
    1.背景函数返回值就是使用return语句终止正在执行的函数,看是很简单的问题有什么说的呢?因为越是简单的问题里面越是有一些不易发现的坑。比如在循环中使用return语句:boolfindChar(conststring&str,constcharc){autosize=str.size();for(decltype(size......
  • Perl中的设计模式革新:命令模式的实现与应用
    Perl中的设计模式革新:命令模式的实现与应用在面向对象编程中,设计模式是解决特定问题的成熟模板。命令模式作为行为设计模式之一,它将请求封装为对象,从而允许用户根据不同的请求对客户进行参数化。本文将深入探讨如何在Perl中实现命令模式,并提供详细的代码示例,帮助开发者在Pe......
  • 【C++BFS 回溯】756. 金字塔转换矩阵
    本文涉及知识点C++BFS算法C++回溯LeetCode756.金字塔转换矩阵你正在把积木堆成金字塔。每个块都有一个颜色,用一个字母表示。每一行的块比它下面的行少一个块,并且居中。为了使金字塔美观,只有特定的三角形图案是允许的。一个三角形的图案由两个块和叠在上面的单......
  • GESP C++ 二级真题(2023年12月)T1 小杨做题
    问题描述:为了准备考试,小杨每天都要做题。第一天做了a道题;第二天做了b道题;从第三天起,小杨每天做的题目数量是前两天的总和。此外,小杨还规定当自己某一天做了大于或等于m题时,接下来的日子,他就不做题了。请问到了第n天,小杨总共做了多少道题?输入描述:总共4行。第一行一个整数a,......
  • 使用GDAL(C++库)从末尾行开始向上读取图像数据
    使用GDAL(C++库)从末尾行读取图像数据OpenCV等图像库默认的读取方式都是从第一行开始,逐行读取数据(自顶向下),填充到内存缓冲区;对于某些特殊应用,需要反行序读取(从末尾行读到起始行)的图像数据结果。GDAL提供了灵活的栅格数据读取方式RasterIO,下面介绍RasterIO的调用方式,以及如何......
  • 在VS2022中通过Nuget将vcpkg环境集成/卸载到c++项目
    在VS2022中通过Nuget将vcpkg环境集成/卸载到c++项目vcpkg是微软和C++社区维护的免费开源C/C++包管理器。利用它,可以一条命令编译安装用户所需的库;提供CMake配置文件;并且对于Windows开发者,在VisualStudio中集成后还可以自动链接静态库,非常方便易用。一般而言,开发者仅需要......