設計模式20-Visitor(訪問者)模式-企業資訊管理
在軟體構建過程中,由於需求的改變,某些類層次結構中常常需要增加新的行為(方法),如果直接在基類中做這樣的更改,將會給子類帶來很繁重的變更負擔,甚至破壞原有設計。那麼如何在不更改類層次結構的前提下,在執行時根據需要透明地為類層次結構上的各個子類動態新增新的操作,從而避免上述問題呢?
這就要用到我們今天要講的訪問者模式了,訪問者模式即表示一個作用於某物件結構中的個元素的操作。使得可以在不改變各元素的類的前提下定義(擴充套件)作用於這些元素的新操作(變化)。
UML圖:
抽象訪問者(Visitor)角色:聲明瞭一個或者多個訪問操作,形成所有的具體元素角色必須實現的介面。
具體訪問者(ConcreteVisitor)角色:實現抽象訪問者角色所宣告的介面,也就是抽象訪問者所宣告的各個訪問操作。
抽象節點(Element)角色:宣告一個接受操作,接受一個訪問者物件作為一個參量。
具體節點(ConcreteElement)角色:實現了抽象元素所規定的接受操作。
結構物件(ObiectStructure)角色:有如下的一些責任,可以遍歷結構中的所有元素;如果需要,提供一個高層次的介面讓訪問者物件可以訪問每一個元素;如果需要,可以設計成一個複合物件或者一個聚集,如列(List)或集合(Set)。
舉個例子,假設我們現在做了一個企業員工資訊管理系統,我們已經把每個員工的基本資訊都存起來了,現在我們想要快速的比較每一個員工的某項資訊的差別,比如年齡、籍貫、學歷、收入等等。
程式碼實現:
#include 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
執行結果:
張三的工資為: 25000李四的工資為: 18000趙五的工資為: 15000張三的年齡為: 25李四的年齡為: 28趙五的年齡為: 27張三的學歷為: 博士李四的學歷為: 碩士趙五的學歷為: 本科