专业的编程技术博客社区

网站首页 > 博客文章 正文

设计模式20-Visitor(访问者)模式-企业信息管理

baijin 2024-10-01 07:32:24 博客文章 8 ℃ 0 评论

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

这就要用到我们今天要讲的访问者模式了,访问者模式即表示一个作用于某对象结构中的个元素的操作。使得可以在不改变各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。

UML图:

  • 抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
  • 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
  • 抽象节点(Element)角色:声明一个接受操作,接受一个访问者对象作为一个参量。
  • 具体节点(ConcreteElement)角色:实现了抽象元素所规定的接受操作。
  • 结构对象(ObiectStructure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。

举个例子,假设我们现在做了一个企业员工信息管理系统,我们已经把每个员工的基本信息都存起来了,现在我们想要快速的比较每一个员工的某项信息的差别,比如年龄、籍贯、学历、收入等等。

代码实现:

#include <iostream>
#include <string>
#include <list>
using namespace std;

class Element;

class Visitor
{
public:
	virtual void Visit(Element *element) {};
};

// "Element"
class Element
{
public:
	// Methods
	virtual void Accept(Visitor *visitor) {};
};


// "ConcreteElement"
class Employee : public Element
{
public:
	string	name;			//姓名
	int		age;			//年龄
	string  hometown;		//籍贯
	string	education;		//学历
	double	income;			//工资

public:
	Employee(string name, int age, string hometown, string education, double income) {
		this->name = name;
		this->age = age;
		this->hometown = hometown;
		this->education = education;
		this->income = income;
	}

	void Accept(Visitor *visitor) {
		visitor->Visit(this);
	}
};

class AgeVisitor : public Visitor
{
public:
	void Visit(Element *element) {
		Employee *employee = ((Employee*)element);
		cout << employee->name << "的年龄为: " << employee->age << endl;
	}
};

class EducationVisitor : public Visitor
{
public:
	void Visit(Element *element) {
		Employee *employee = ((Employee*)element);
		cout << employee->name << "的学历为: " << employee->education << endl;

	}
};

class IncomeVisitor : public Visitor
{
public:
	void Visit(Element *element) {
		Employee *employee = ((Employee*)element);
		cout << employee->name << "的工资为: " << employee->income << endl;

	}
};

// "ObjectStructure"
class Employees
{
private:
	list< Employee*> employees;

public:

	void Attach(Employee *employee)
	{
		employees.push_back(employee);
	}

	void Detach(Employee *employee)
	{
		employees.remove(employee);
	}

	void Accept(Visitor *visitor)
	{
		for (std::list<Employee*>::iterator it = employees.begin(); it != employees.end(); ++it)
			(*it)->Accept(visitor);
	}
};

void main()
{
	Employees *e = new Employees();
	e->Attach(new Employee("张三", 25, "南京", "博士", 25000.0));
	e->Attach(new Employee("李四", 28, "上海", "硕士", 18000.0));
	e->Attach(new Employee("赵五", 27, "杭州", "本科", 15000.0));

	// 创建访问者
	IncomeVisitor *v1 = new IncomeVisitor();
	AgeVisitor *v2 = new AgeVisitor();
	EducationVisitor *v3 = new EducationVisitor();

	// 访问员工信息
	e->Accept(v1);
	e->Accept(v2);
	e->Accept(v3);
}

运行结果:

张三的工资为: 25000
李四的工资为: 18000
赵五的工资为: 15000
张三的年龄为: 25
李四的年龄为: 28
赵五的年龄为: 27
张三的学历为: 博士
李四的学历为: 硕士
赵五的学历为: 本科

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表