Design Pattern-Visitor pattern

Source: Internet
Author: User

The design pattern book defines the visitor pattern as an operation that acts on each element of an object structure. It allows you to define new operations that act on these elements without changing the classes of each element. From the definition, we can see that the structure object is a required condition for using the visitor mode, and this structure object must have a method to traverse its own objects.

Imagine a scenario where there are teachers and students in the school. Teachers and students can be called two elements. We can perform many operations on these elements (note, these operations are external and do not belong to the elements themselves. This is vital), such as evaluation, questionnaire survey, interview, and health check. If we define these operations at the element level, obviously unreasonable. First, these operations are not inherent attributes and behaviors of element objects, but some external operations, which do not conform to the principle of object-oriented encapsulation and single responsibility. It is obviously unreasonable to define these operations on the school layer because the school only manages teachers and students, and these operations are not the responsibility of the school. Since it cannot be defined at the element layer or the school layer, we can define a single hierarchy to implement it, but there are two problems here, first, these operations may have different forms for different elements. Second, these operations must also be permitted by elements, that is, they can receive your access. The preceding scenario is actually a typical application scenario of the visitor mode. The following is a brief description of the visitor:

The implementation code for the above scenario:

Using system;
Using system. Collections. Generic;
Using system. text;

Namespace designmodelstudy
{
Public abstract class person
{
Public abstract void accept (person_visitor VA );
Public abstract int getpersontype ();
}

// Studeng object.
Class student: person
{
Private int _ id;
Private string _ name;
Public override int getpersontype ()
{
Return 1;
}
Public student (int id, string name)
{
This. _ name = Name;
This. _ id = ID;
}
Public int ID
{
Get
{
Return this. _ id;
}
Set
{
This. _ id = value;
}
}
Public string name
{
Get
{
Return this. _ name;
}
Set
{
This. _ name = value;
}
}
Public override void accept (person_visitor VA)
{
System. Windows. Forms. MessageBox. Show (va. Visit (this ));
}
}
// Teacher object.
Class Teacher: person
{
Private int _ id;
Private string _ name;
Private int _ age;
Public Teacher (int id, string name, int age)
{
This. _ name = Name;
This. _ id = ID;
This. _ age = age;
}
Public int ID
{
Get
{
Return this. _ id;
}
Set
{
This. _ id = value;
}
}
Public string name
{
Get
{
Return this. _ name;
}
Set
{
This. _ name = value;
}
}
Public int age
{
Get
{
Return this. _ age;
}
Set
{
This. _ age = value;
}
}
Public override void accept (person_visitor VA)
{
System. Windows. Forms. MessageBox. Show (va. Visit (this ));
}
Public override int getpersontype ()
{
Return 2;
}
}
// Personnel Management
Class School
{
Private system. Collections. arraylist _ students;
Public School ()
{
_ Students = new system. Collections. arraylist ();
}
Public void add (person st)
{
If (this. _ students. indexof (ST) <0)
{
This. _ students. Add (ST );
}
}
Public void del (person st)
{
This. _ students. Remove (ST );
}
Public Person getstudent (INT index)
{
If (index> = 0 & index <this. _ students. Count)
{
Return (person) This. _ students [Index];
}
Return NULL;
}
Public person this [int Index]
{
Get
{
If (index> = 0 & index <this. _ students. Count)
{
Return (person) This. _ students [Index];
}
Return NULL;
}
}
Public int count
{
Get
{
Return this. _ students. count;
}
}
}


Public abstract class person_visitor
{
Public abstract string visit (person P );
}
// Evaluate personnel
Public class evaluatevisit: person_visitor
{
Public override string visit (person P)
{
If (P is student)
{
Return "Student:" + (student) P). Name + "comment" + "Result: 10 ";
}
Else
{
Return "Instructor:" + (teacher) P ). name + "" + "Age:" + (teacher) P ). age. tostring () + "Evaluation Result: 30 ";
}

}
}
// Interview personnel
Public class interviewvisit: person_visitor
{
Public override string visit (person P)
{
If (P is student)
{
Return "Student:" + (student) P). Name + "interviewed" + "Result: 10 ";
}
Else
{
Return "Instructor:" + (teacher) P). Name + "interviewed" + "Age:" + (teacher) P). Age. tostring ();
}

}
}
Public class visitortest
{
Private school _ pmgr;
Public visitortest ()
{
_ Pmgr = New School ();
}
Public void createdatas ()
{
Random RD = new random ();

For (INT I = 0; I <10; I ++)
{
If (I % 2) = 1)
{
This. _ pmgr. Add (new student (I, "student" + I. tostring ()));
}
Else
{
This. _ pmgr. Add (new teacher (I, "" + I. tostring (), 30 + convert. toint32 (RD. nextdouble () * 100 )));
}
}
}
Public void test ()
{
Evaluatevisit EV = new evaluatevisit ();
For (INT I = 0; I <this. _ pmgr. Count; I ++)
{
This. _ pmgr [I]. Accept (EV );
}
}
}
}
Summary:

1) The visitor mode provides a method to separate and decouple the data structure and the Operations attached to the data structure. Of course, the visitor mode should be used, A necessary condition is that there are many data elements and a set-based management is required. The reason is very simple. If the number of elements in the data structure is relatively small and batch processing is not allowed (the benefit of the set is that batch processing can be performed), there is no advantage in using the visitor mode.

2) The visitor mode is suitable for managing a large number of elements (such as a set, combination, and tree structure) and requires additional operations (but many operations, great changes, and uncertainty) processing location.

3) The visitor mode is generally used in combination with the set mode.

4) Note that the visitor mode is not used to separate the data attributes of the class from the Operation attributes. The visitor mode provides a way to coordinate and manage data elements and additional operations.

 

Note: There are many places in the current programming language that adopt this mode, such as stream, reader, and writer in stream operations, and iteration and query of enumerated objects.

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.