大家好,欢迎来到IT知识分享网。
在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。那么如何在不更改类层次结构的前提下,在运行时根据需要透明地为类层次结构上的各个子类动态添加新的操作,从而避免上述问题呢?
这就要用到我们今天要讲的访问者模式了,访问者模式即表示一个作用于某对象结构中的个元素的操作。使得可以在不改变各元素的类的前提下定义(扩展)作用于这些元素的新操作(变化)。
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 张三的学历为: 博士 李四的学历为: 硕士 赵五的学历为: 本科
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/138626.html