Visitor design pattern for beginners.
Background –
I hope you have remembered implicit
and explicit trusting. If not, then please go through this link. Visitor design pattern uses explicit trusting.
It means an external system will share its signature and you (the class designer) have to make a decision, whether to accept it or not, once you accept it, the external system has authority
to change the state of your object.
Training programs are a perfect example of the visitor design
pattern. Where you will decide whether to take the training based on the teacher’s signature (identity or popularity). Once you have accepted training, the teacher will ask, your current knowledge on a particular topic. Which is
nothing but your private information (or say internal state of the object), then the trainer will change (improve) your knowledge
on the same topic through his/her training.
Here we are talking about exposing the object’s private
information with the external system.
Now take trainer as a visitor object and
student as element object. We will have many trainers (visitor object) for different
subject, and we also have many students (element object) subjects.
That is why we have an abstract visitor class and its different concrete implementations.
Now understand the concept, teaching is not the behavior of the student, but there is a need for behavior changes in many student objects (become
more proficient in subject X). So we use visitor object to make the changes.
Why do we need the visitor design pattern?
Think, there is a need for behavioral changes (or say new requirements
on old behavior) for your class. You are looking out away, where other classes can
do it for you, so that you can achieve that behavioral change, without having structural
changes in your class. Or say without modifying (or adding more complexity, or
making it more dirty) class, achieve behavioral change.
UML Structure -
Different components of UML structure -
- Visitor - it is an interface class, which will define visit API. Concrete implementation class will implement it.
- Concrete visitor - implementation of APIs declared in visitor interface.
- Element - this will give a general interface for all classes who are going to implement visitor, through accept API call. So all desire classes shall get inherited from it.
- Concrete element - is your real implementation classes, which will contain business logic in it.
C++ Example -
Example of visitor design pattern (Click on picture to see zoom view) |
#include<iostream> using namespace std; class DepartmentX; class DepartmentY; class Visitor { public: virtual void Visit(DepartmentX& ) = 0; virtual void Visit(DepartmentY& ) = 0; }; class Employee { public: virtual void Accept(class Visitor *externalTrainer) = 0; }; class DepartmentX : public Employee { public: void Accept(Visitor *externalTrainer) { externalTrainer->Visit(*this); } void ImproveKnowledge() { cout<<"Improve knowledge "<<endl; } }; class DepartmentY : public Employee { public: void Accept(Visitor *externalTrainer) { externalTrainer->Visit(*this); } void ImproveKnowledge() { cout<<"Improve knowledge "<<endl; } }; //-------------------------------------------------------------------------------------------------- // Class class CPPTrainer : public Visitor { public: void Visit(DepartmentX& dept) { dept.ImproveKnowledge(); cout<<"Improving CPP knowledge of DepartmentX"<<endl; } void Visit(DepartmentY& dept) { dept.ImproveKnowledge(); cout<<"Improving CPP knowledge of DepartmentY"<<endl; } }; //-------------------------------------------------------------------------------------------------- // Class class JavaTrainer : public Visitor { public: void Visit(DepartmentX& dept) { dept.ImproveKnowledge(); cout<<"Improving Java knowledge of DepartmentX"<<endl; } void Visit(DepartmentY& dept) { dept.ImproveKnowledge(); cout<<"Improving Java knowledge of DepartmentY"<<endl; } }; /* ####################################################################################### ######### __ __ _ ###################################################### ######### | \/ | __ _(_)_ __ ###################################################### ######### | |\/| |/ _` | | '_ \ ###################################################### ######### | | | | (_| | | | | | ###################################################### ######### |_| |_|\__,_|_|_| |_| ###################################################### ####################################################################################### */ int main(int argc, char** argv) { Employee *pEmployee[] = {new DepartmentX, new DepartmentY}; Visitor *pTrainers[] = {new CPPTrainer, new JavaTrainer}; //Improving CPP knowledge of All department for(int index = 0; index < 2; index++) { pEmployee[index]->Accept(pTrainers[0]); } //Improving Java knowledge of All department for(int index = 0; index < 2; index++) { pEmployee[index]->Accept(pTrainers[1]); } delete [] pEmployee; delete [] pTrainers; return 0; } ///////////////////////////////////////////////////////////////////-------------OutPut /* kbaghel@MSDN_L7-5CG5111 /home/kbaghel/dev/github/DesignPatterns/03LLD-GoF_Patterns/behavioral/visitor/src/my $ ./a.exe Improve knowledge Improving CPP knowledge of DepartmentX Improve knowledge Improving CPP knowledge of DepartmentY Improve knowledge Improving Java knowledge of DepartmentX Improve knowledge Improving Java knowledge of DepartmentY */
Thanks for reading it. To learn more about design patterns and basic design principles, please see my web page.
Comments
Post a Comment