Visitor mode-Design pattern learning

Source: Internet
Author: User

The visitor pattern (Visitor), which represents an operation that acts on elements in an object structure. It allows you to define new actions that act on these elements without changing the class of each element.

Here is a diagram of the visitor pattern:

    

As you can see from the class diagram, the visitor pattern is quite complicated!

The basic code structure for the visitor pattern is given below:

namespaceconsoleapplication1{//The visitor class, which declares a visit operation for each class concreteelement in the object structure.     Abstract classVisitor { Public Abstract voidVisitconcreteelementa (Concreteelementa concreteelementa);  Public Abstract voidvisitconcreteelementb (Concreteelementb concreteelementb); }    //ConcreteVisitor1 and ConcreteVisitor2 classes, specific visitors, implement each action declared by visitor. Part of each operation implementation algorithm//the algorithm fragment is the class of the object in the corresponding structure.    classConcretevisitor1:visitor { Public Override voidVisitconcreteelementa (Concreteelementa concreteelementa) {Console.WriteLine ("{0} accessed by {1}", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidvisitconcreteelementb (Concreteelementb concreteelementb) {Console.WriteLine ("{0} accessed by {1}", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }           classConcretevisitor2:visitor { Public Override voidVisitconcreteelementa (Concreteelementa concreteelementa) {Console.WriteLine ("{0} accessed by {1}", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidvisitconcreteelementb (Concreteelementb concreteelementb) {Console.WriteLine ("{0} accessed by {1}", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }    //element class, which defines a ACCEPR operation that takes a visitor as a parameter    Abstract classElement { Public Abstract voidAccept (Visitor Visitor); }    //Concreteelementa class and Concreteelementb class, concrete elements, implement accept class    classconcreteelementa:element { Public Override voidAccept (Visitor Visitor) {Visitor. Visitconcreteelementa ( This); }         Public voidOperationa () {}}classconcreteelementb:element { Public Override voidAccept (Visitor Visitor) {Visitor. VISITCONCRETEELEMENTB ( This); }         Public voidoperationb () {}}//The Objectstructure class, which can enumerate its elements, can provide a high-level interface to allow visitors to access its elements    classObjectstructure {Privateilist<element> elements =NewList<element>();  Public voidAttach (element Element) {elements.        ADD (Element); }         Public voidDetach (element Element) {elements.        Remove (Element); }         Public voidAccept (Visitor Visitor) {foreach(Element Einchelements)            {e.accept (visitor); }        }    }    classProgram {Static voidMain (string[] args) {objectstructure o=Newobjectstructure (); O.attach (NewConcreteelementa ()); O.attach (NewCONCRETEELEMENTB ()); ConcreteVisitor1 v1=NewConcreteVisitor1 (); ConcreteVisitor2 v2=NewConcreteVisitor2 ();            O.accept (v1);            O.accept (v2);        Console.readkey (); }    }  }

The output results are as follows:

  

The visitor pattern is suitable for a system with relatively stable data structures, which frees up the coupling between the structure and the operation of the structure, allowing the set of operations to evolve relatively freely.

The purpose of the visitor pattern is to separate the processing from the data structure. Many systems can be separated according to the algorithm and data structure, if such a system has a relatively stable data structure, and there are easy to change the algorithm, the use of the visitor pattern is more appropriate, because the visitor pattern makes the operation of the algorithm more easy. Conversely, if such a system's data structure objects are easy to change, it is often necessary to have new data objects added in, it is not appropriate to use the visitor pattern.

A bit of the visitor pattern is that it's easy to add new operations because adding new operations means adding a new visitor. The visitor pattern concentrates the behavior on a visitor object.

The disadvantage of the visitor pattern is that it becomes difficult to add new data structures.

It is important to note that systems with relatively stable data structures are suitable for visitor patterns, such as men's and women's examples in "Big talk design mode", only men or women.

  

namespaceconsoleapplication1{Abstract classAction {//get a man's conclusion or reaction         Public Abstract voidgetmanconclusion (man Concreteelementa); //get a woman's conclusion or reaction         Public Abstract voidgetwomanconclusion (Woman concreteelementb); }    Abstract classPerson {//Accept         Public Abstract voidAccept (Action visitor); }    //success specific "state" class    classsuccess:action { Public Override voidgetmanconclusion (man Concreteelementa) {Console.WriteLine ("{0}{1}, there's probably a great woman behind it. ", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidgetwomanconclusion (Woman concreteelementb) {Console.WriteLine ("{0}{1}, most of them have an unsuccessful man behind them. ", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }    //failure specific "state" class    classfailing:action { Public Override voidgetmanconclusion (man Concreteelementa) {Console.WriteLine ("{0}{1}, when drinking, no one should persuade. ", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidgetwomanconclusion (Woman concreteelementb) {Console.WriteLine ("{0}{1}, tears, no one can persuade. ", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }    //Love specific "state" class    classamativeness:action { Public Override voidgetmanconclusion (man Concreteelementa) {Console.WriteLine ("{0}{1}, usually do not understand, but also to be installed to understand. ", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidgetwomanconclusion (Woman concreteelementb) {Console.WriteLine ("{0}{1}, when you do not understand. ", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }    //male Human    classMan:person { Public Override voidAccept (Action visitor) {visitor. Getmanconclusion ( This);//first, the client program passes the specific state as a parameter to the "Man" class to complete a dispatch, and then the "Man" class is called as the "specific state" of the parameter.//in the method, "The man reacts", at the same time, he (this) as a parameter passed in. This completes the second dispatch.        }    }    //female human    classWoman:person { Public Override voidAccept (Action visitor) {visitor. Getwomanconclusion ( This); }    }    //Object Structure    classObjectstructure {Privateilist<person> elements =NewList<person>(); //Increase         Public voidAttach (person Element) {elements.        ADD (Element); }        //removed from         Public voidDetach (person Element) {elements.        Remove (Element); }        //View Display         Public voidDisplay (Action visitor) {foreach(Person Pinchelements)            {p.accept (visitor); }        }    }    classProgram {Static voidMain (string[] args) {objectstructure o=Newobjectstructure (); O.attach (NewMan ()); O.attach (NewWoman ()); //the response when successfulSuccess V1 =NewSuccess ();            O.display (v1); //the reaction when it failsFailing v2 =Newfailing ();            O.display (v2); //the reaction in loveAmativeness v3 =Newamativeness ();            O.display (v3);        Console.readkey (); }    }  }

The results are as follows:

    

What good does it do?

If you want to add a marriage status to investigate the reaction of men and women, because of the use of double allocation, just add a "state" subclass, you can use the client calls to view, no need to change any other class of code.

    //Marriage Status Class    classmarriage:action { Public Override voidgetmanconclusion (man Concreteelementa) {Console.WriteLine ("{0}{1}, feeling to: The end of the love game, ' have a wife sentence ' remote", Concreteelementa.gettype (). Name, This. GetType ().        Name); }         Public Override voidgetwomanconclusion (Woman concreteelementb) {Console.WriteLine ("{0}{1}, Happy Yue: Love long-distance running road, marriage insurance to protect the peace", Concreteelementb.gettype (). Name, This. GetType ().        Name); }    }

Client Add:

            // Client Add            New marriage ();            O.display (v4);

Visitor mode-Design pattern learning

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.