访问器模式(C++)

定义

表示一个作用于某对象结构中的各元素的操作。使得可以在不改变(稳定)各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。

应用场景

  • 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。
  • 如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作,从而避免上述问题?

结构

在这里插入图片描述

代码示例

//Visitor.h
/****************************************************/
#ifndef VISITOR_H
#define VISITOR_H
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
 
using namespace std;
 
class Visitor;
 
// 抽象元素类-地点(被访问)
class Place 
{
public:
	// 构造函数
	Place(string name) : m_name(name) {}
 
	// 接受访问
	virtual void accept(Visitor* visitor) = 0;
 
	// 获取名字
	string getName() {
		return m_name;
	}
 
private:
	string m_name;
};
 
// 具体元素类-学校
class School : public Place 
{
public:
	// 构造函数
	School(string name) : Place(name) {}
 
	// 接受访问
	virtual void accept(Visitor* visitor);
 
};
 
// 具体元素类-企业
class Enterprise : public Place 
{
public:
	// 构造函数
	Enterprise(string name) : Place(name) {}
 
	// 接受访问
	virtual void accept(Visitor* visitor);
 
};
 
// 抽象访问者
class Visitor 
{
public:
	// 访问学校
	virtual void visitSchool(School* school) = 0;
 
	// 访问企业
	virtual void visitEnterprise(Enterprise* enterprise) = 0;
 
};
 
// 具体访问者-市长
class Mayor : public Visitor 
{
public:
	// 访问学校
	virtual void visitSchool(School* school) {
		cout << "市长参观了:" << school->getName() << endl;
		cout << "对老师和学生表达了诚挚的慰问。" << endl;
	}
 
	// 访问企业
	virtual void visitEnterprise(Enterprise* enterprise) {
		cout << "市长参观了:" << enterprise->getName() << endl;
		cout << "对企业的发展表示肯定。" << endl;
	}
 
};
 
// 访问行为类
class Visiting
{
public:
	// 添加被访问地点
	void add(Place* place) {
		places.push_back(place);
	}
 
	// 删除被访问地点
	void remove(Place* place) {
		places.erase(std::remove(places.begin(), places.end(), place), places.end());
	}
 
	// 进行访问
	void accept(Visitor* visitor) {
		for (auto place : places) {
			place->accept(visitor);
		}
	}
 
private:
	std::vector<Place*> places;
};

// 接受访问
void School::accept(Visitor* visitor) {
	visitor->visitSchool(this);
}
 
// 接受访问
void Enterprise::accept(Visitor* visitor) {
	visitor->visitEnterprise(this);
}

#endif
//test.cpp
/****************************************************/
#include "Visitor.h"
 
int main()
{
	Visiting *visiting = new Visiting();
	Place *school = new School("东华大学");
	Place *enterprise = new Enterprise("华为");
	Visitor *mayor = new Mayor();
 
	// 添加被访问对象
	cout << "首日,";
	visiting->add(school);
	visiting->add(enterprise);
	// 安排市长进行访问
	visiting->accept(mayor);
	// 次日行程,删除某个被访问对象后再次访问
	cout << "次日,";
	visiting->remove(school);
	visiting->accept(mayor);
 
	// 删除
	delete visiting;
	delete school;
	delete enterprise;
	delete mayor;
	visiting = nullptr;
	school = nullptr;
	enterprise = nullptr;
	mayor = nullptr;
	return 0;
}

运行结果
在这里插入图片描述

要点总结

  • Visitor模式通过所谓双重分发(double dispatch)来实现在不更改(不添加新的操作编译时) Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作(支持变化)。
  • 所谓双重分发即Visitor模式中间包括了两个多态分发(注意其中的多态机制) :第一个为accept方法的多态辨析;第二个为visitElementX方法的多态辨析。
  • Visitor模式的最大缺点在于扩展类层次结构(增添新的Element子类),会导致Visitor类的改变。因此Vistor模式适用于“Element类层次结构稳定,而其中的操作却经常面临频繁改动”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 迭代模式是设计模式的一种,它定义了一种创建聚合对象的迭代的方法,以便遍历聚合中的所有元素,而不需要暴露该对象的内部表示。 通过使用迭代模式,我们可以隐藏遍历聚合对象内部元素的细节,并且在不改变聚合对象结构的情况下添加新的遍历方法。 在C语言中,迭代模式通常通过定义指向当前元素的指针和接口来实现,以便从外部代码遍历聚合对象。 ### 回答2: 迭代模式是一种行为设计模式,它通过提供一种顺序访问一个聚合对象中各个元素的方法,而不需要暴露该对象的内部表示方式。在C语言中,可以使用函数指针来实现迭代模式。 在使用迭代模式时,首先需要定义一个聚合对象,即包含一组元素的数据结构。然后定义一个迭代接口,其中包含用于访问聚合对象元素的方法,比如获取下一个元素、判断是否还有下一个元素等。 为了实现迭代模式,可以定义一个函数指针类型,表示迭代的操作方法。然后在聚合对象中,将函数指针作为成员变量存储。这样,迭代对象就可以通过函数指针来访问聚合对象中的元素。 在使用迭代模式时,首先创建一个迭代对象,并将其与待访问的聚合对象关联起来。然后可以通过调用迭代的方法来访问聚合对象中的元素,直到没有更多元素为止。 迭代模式在C语言中的应用非常广泛,可以帮助我们更方便地访问各种数据结构,比如链表、数组等。通过封装迭代对象和聚合对象的细节,可以提高代码的可维护性和可复用性。 总之,迭代模式是一种简洁而强大的设计模式,在C语言中可以通过使用函数指针来实现。它能够帮助我们更方便地访问聚合对象中的元素,提高代码的可维护性和可复用性。 ### 回答3: 迭代模式是一种行为型设计模式,它允许程序按照特定的方式遍历一个容对象中的元素,而不暴露容对象的内部结构。在C语言中,我们可以通过使用指针和函数指针实现迭代模式。 在C语言中,通常使用结构体来表示容对象,结构体中包含保存元素的数组以及其他与容相关的信息。迭代则是一个指向特定类型元素的指针,并且提供了一组操作函数,以实现对容中元素的迭代访问。 首先,在定义结构体时,我们需要为结构体实现迭代相关的操作函数,包括初始化迭代、获取当前元素、向后移动迭代等。这些操作函数需要通过函数指针来实现,以便在使用迭代时可以根据具体的迭代类型动态调用相应的函数。 接下来,在操作容对象时,我们可以通过初始化迭代函数获取到迭代对象,并使用迭代的操作函数来遍历容中的元素。通过调用迭代的不同操作函数,我们可以实现向前或向后遍历容中的元素,并获取当前元素的值。 使用迭代模式可以使得对容对象的遍历处理与容对象的内部结构相分离,从而提高代码的可维护性和扩展性。迭代模式也可以隐藏容对象的细节,使其对外界更加封闭,符合面向对象设计的封装性原则。 总之,C语言中可以通过使用指针和函数指针来实现迭代模式。通过定义迭代的相关操作函数,以及结合容对象的使用,我们可以实现对容中元素的迭代访问

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值