One, Introduction

   Let's start today“ Behavior type” The ninth pattern of design pattern, The mode is【 Visitor mode】, The English name is:Visitor
Pattern. If you follow the old rules, Let's first look at the pattern by name, I can't get any information that's useful for understanding the pattern, And this pattern is not used very much in our coding life. The intent definition of the pattern is abstract, The first time I read this definition, it's no different from no reading, In a fog, In order to better understand the original intention of the model, Let's give an example to illustrate the pattern. such as: When we want to solve a new software requirement, After many days and nights of hard work, Finally through a perfect( What I think) The software design based on asp.net solves the new requirements of customers, And this design has a perfect class hierarchy, And it's consistent withOO Of design principles, We are very happy, I have a great sense of achievement in my design. It's been a while, The customer suddenly has a new demand, You need to add a new operation to the existing class hierarchy( It's a way), How to do it?? Easy to handle, In the face ofOO One of the design patterns is to solve this problem, That is“ Visitor mode”, New operations can be easily added for classes in the existing class hierarchy, Let's move on, Take a good look at the model.

Two, Detailed introduction to visitor mode

2.1, motivation(Motivate)

  
In the process of software construction, Due to changes in demand, New behaviors often need to be added in some class hierarchies( Method), If you make such a change directly in the base class, It will bring heavy change burden to subclasses, Even destroy the original design. How to change the class hierarchy without changing it, Transparently add new operations to each class on the class hierarchy at runtime as needed, So as to avoid the above problems?

2.2, intention(Intent)

  
Represents an operation that acts on elements in an object structure. It can define new operations on elements without changing their classes.                                     
——《 Design pattern》GoF

2.3, Structural drawing(Structure)

    

2.4, Composition of the model
    
    It can be seen that, In the structure diagram of visitor mode, there are the following roles:

    (1), Abstract visitor role(Vistor):
Declare one including multiple access operations, Multiple operations for multiple specific node roles( It can be said that there are as many access operations as there are specific node roles), Interface that all specific visitors must implement.

    (2), Specific visitor roles(ConcreteVistor): Implements all declared interfaces in the abstract visitor role, It can also be said to implement new operations for each specific node role.

    (3), Abstract node role(Element): Declare an accept operation, Accept an accessor object as a parameter, If there are other parameters, It can be here“ Accept operation” Defining the relevant parameters in.

    (4), Specific node roles(ConcreteElement): Implement the accept operation specified by the abstract element.

    (5), Structure object role(ObjectStructure): Container for node, Can contain multiple containers with different types or interfaces.

2.5, Code implementation of visitor pattern

   
Visitor pattern is not used very much in our real coding life, I'll post the code directly, Let's see the structure of the code. Today, I will give you two code examples, Let's experience the visitors. The implementation code is as follows:
1 namespace Vistor 2 { 3 // Abstract graphic definition--- Amount to“ Abstract node role”Element 4 public abstract
class Shape 5 { 6 // Drawing graphics 7 public abstract void Draw(); 8 // External injection of specific visitors 9
public abstract void Accept(ShapeVisitor visitor); 10 } 11 12 // Abstract Visitor
Visitor 13 public abstract class ShapeVisitor 14 { 15 public abstract void
Visit(Rectangle shape); 16 17 public abstract void Visit(Circle shape); 18 19
public abstract void Visit(Line shape); 20 21 //
Here's one thing to say:Visit Method parameters can be written asShape Do you? This is it Visit(Shape
shape), Certainly. howeverShapeVisitor SubclassVisit Method needs to judge the currentShape What kind is it, yesRectangle type, yesCircle type, OrLine type.
22 } 23 24 // Specific visitors ConcreteVisitor 25 public sealed class CustomVisitor :
ShapeVisitor 26 { 27 // In the light ofRectangle object 28 public override void Visit(Rectangle
shape) 29 { 30 Console.WriteLine(" In the light ofRectangle New operation!"); 31 } 32 // In the light ofCircle object
33 public override void Visit(Circle shape) 34 { 35 Console.WriteLine("
In the light ofCircle New operation!"); 36 } 37 // In the light ofLine object 38 public override void Visit(Line
shape) 39 { 40 Console.WriteLine(" In the light ofLine New operation!"); 41 } 42 } 43 44 //
rectangle---- Amount to“ Specific node roles” ConcreteElement 45 public sealed class Rectangle : Shape 46
{ 47 public override void Draw() 48 { 49 Console.WriteLine(" Rectangle I've drawn!"); 50
} 51 52 public override void Accept(ShapeVisitor visitor) 53 { 54
visitor.Visit(this); 55 } 56 } 57 58 // circular--- Amount to“ Specific node roles”ConcreteElement 59
public sealed class Circle : Shape 60 { 61 public override void Draw() 62 {
63 Console.WriteLine(" I've drawn the circle!"); 64 } 65 66 public override void
Accept(ShapeVisitor visitor) 67 { 68 visitor.Visit(this); 69 } 70 } 71
72 // straight line--- Amount to“ Specific node roles” ConcreteElement 73 public sealed class Line : Shape 74
{ 75 public override void Draw() 76 { 77 Console.WriteLine(" I have drawn the straight line!"); 78
} 79 80 public override void Accept(ShapeVisitor visitor) 81 { 82
visitor.Visit(this); 83 } 84 } 85 86 // Structure object role 87 internal class
AppStructure 88 { 89 private ShapeVisitor _visitor; 90 91 public
AppStructure(ShapeVisitor visitor) 92 { 93 this._visitor = visitor; 94 } 95
96 public void Process(Shape shape) 97 { 98 shape.Accept(_visitor); 99 }
100 } 101 102 class Program 103 { 104 static void Main(string[] args) 105 {
106 // If you want to perform a new operation 107 ShapeVisitor visitor = new CustomVisitor(); 108
AppStructure app =new AppStructure(visitor); 109 110 Shape shape = new
Rectangle();111 shape.Draw();// Perform your own actions 112 app.Process(shape);// Perform new actions 113 114
115 shape = new Circle(); 116 shape.Draw();// Perform your own actions 117 app.Process(shape);//
Perform new actions 118 119 120 shape = new Line(); 121 shape.Draw();// Perform your own actions 122
app.Process(shape);// Perform new actions 123 124 125 Console.ReadLine(); 126 } 127 } 128 }
This is the second code instance of visitor mode:
1 namespace Visitor 2 { 3 // Abstract visitor role Visitor 4 public abstract class Visitor
5 { 6 public abstract void PutTelevision(Television tv); 7 8 public
abstract void PutComputer(Computer comp); 9 } 10 11 // Specific visitor roles
ConcreteVisitor 12 public sealed class SizeVisitor : Visitor 13 { 14 public
override void PutTelevision(Television tv) 15 { 16 Console.WriteLine("
By product size{0} discharge", tv.Size); 17 } 18 19 public override void PutComputer(Computer
comp) 20 { 21 Console.WriteLine(" By product size{0} discharge", comp.Size); 22 } 23 } 24
25 // Specific visitor roles ConcreteVisitor 26 public sealed class StateVisitor : Visitor 27
{ 28 public override void PutTelevision(Television tv) 29 { 30
Console.WriteLine(" By old and new value of goods{0} discharge", tv.State); 31 } 32 33 public override void
PutComputer(Computer comp) 34 { 35 Console.WriteLine(" By old and new value of goods{0} discharge",
comp.State); 36 } 37 } 38 39 // Abstract node role Element 40 public abstract class
Goods 41 { 42 public abstract void Operate(Visitor visitor); 43 44 private
int nSize; 45 public int Size 46 { 47 get { return nSize; } 48 set { nSize
= value; } 49 } 50 51 private int nState; 52 public int State 53 { 54
get { return nState; } 55 set { nState = value; } 56 } 57 } 58 59 //
Specific node roles ConcreteElement 60 public sealed class Television : Goods 61 { 62
public override void Operate(Visitor visitor) 63 { 64 visitor.PutTelevision(
this); 65 } 66 } 67 68 // Specific node roles ConcreteElement 69 public sealed class
Computer : Goods 70 { 71 public override void Operate(Visitor visitor) 72 {
73 visitor.PutComputer(this); 74 } 75 } 76 77 // Structure object role 78 public sealed
class StoragePlatform 79 { 80 private IList<Goods> list = new List<Goods>();
81 82 public void Attach(Goods element) 83 { 84 list.Add(element); 85 }
86 87 public void Detach(Goods element) 88 { 89 list.Remove(element); 90
} 91 92 public void Operate(Visitor visitor) 93 { 94 foreach (Goods g in
list) 95 { 96 g.Operate(visitor); 97 } 98 } 99 } 100 101 class Program
102 { 103 static void Main(string[] args) 104 { 105 StoragePlatform platform =
new StoragePlatform(); 106 platform.Attach(new Television()); 107
platform.Attach(new Computer()); 108 109 SizeVisitor sizeVisitor = new
SizeVisitor();110 StateVisitor stateVisitor = new StateVisitor(); 111 112
platform.Operate(sizeVisitor);113 platform.Operate(stateVisitor); 114 115
Console.Read();116 } 117 } 118 }

Three, The implementation of visitor pattern:

    Visitor Through the so-called dual distribution(double
dispatch) Come on, don't change nowElement Under the premise of class hierarchy, Transparently add new operations to each class in the class hierarchy at runtime. The so-called double distribution isVisitor Two polymorphic distributions are included in the pattern( Pay attention to the mechanism of polymorphism): The first isaccept Analysis of the polymorphism of methods; The second isvisit Analysis of the polymorphism of methods.


   Design pattern is actually a way to close the loopholes, But no design pattern can close all the holes, It's the same even when you combine design patterns. Every design pattern has flaws, There are situations or changes that they can't solve. Each design pattern assumes a change, It's assumed that there's some kind of immutability.Visitor The pattern assumes that the operation changes, andElement Class hierarchy is stable.

    (1), The main advantages of the visitor model are:

       
1】, Visitor mode makes it easy to add new operations. If some operations depend on a complex structural object, So in general, Adding new operations can be complex. Use visitor mode, Adding a new action means adding a new visitor class. therefore, Make it easy to add new operations.

        2】, Visitor mode enables related behavior operations to be concentrated in one visitor object, Instead of dispersing into element classes. This is similar to” Intermediary model”.

        3】, Visitor pattern can access member objects belonging to different hierarchies, Iteration can only access member objects belonging to the same hierarchy.

 (2), The main disadvantages of visitor mode are:

       
1】, Adding new element classes becomes difficult. Adding a new element means adding a new abstract operation to the abstract visitor role, And add corresponding specific operations to each specific visitor class. say concretely,Visitor The biggest disadvantage of schema is to extend the class hierarchy( Add newElement Subclass), May lead toVisitor Class changes. thereforeVisitor Mode applies to“Element Class hierarchy is stable, But the operation often faces frequent changes”.

    (3), Consider using the visitor pattern in the following cases:

        1】, If the system has a relatively stable data structure, When there are algorithms that are easy to change, Consider using the visitor pattern at this point. Because the visitor mode makes it easy to add algorithm operations.

        2】, If a group of classes, There are similar operations, To avoid a lot of duplicate code, Consider encapsulating repetitive actions into visitors.( Of course, you can also consider using abstract classes)

        3】, If there are some objects that are not related to their own objects, Or operation with weak relationship, To avoid contamination of this object by operation, Consider encapsulating these operations into the visitor object.


Four,.NET Implementation of visitor pattern

    
In the presentNet Inside the frame, If you want to add a new method to an existing class, There's a new way, That is“ Extension method”, It is the same as the instance method, And inNet Inside the frame, Microsoft has also written many extension methods for us to use. I haven't learned yetNet The framework class library of“ Visitor mode” Realization, It seems that I still need to work hard, The revolution is not yet successful.

Five, summary

   
Visitor mode is finished, It's a very difficult model to understand at the beginning, however, If we look at a few more instance codes, Complete mastery is not a problem. along withC# The development of language, A lot of things in design patterns, We can go throughC# Some features of language make a better alternative. We need to write design patterns slowly at the beginning, Write the code step by step, When we master the core meaning of the model, We're going to write a matchC# Pattern code for styles and features, Or we need to useC# Here's the design pattern, The code will be better.