CSharp: Visitor Pattern in donet core 3

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/// <summary>
/// 访问者模式  Visitor Pattern
/// geovindu,Geovin Du eidt   
/// </summary>
interface IEmployee
{
    /// <summary>
    /// To set an employee name
    /// </summary>
    string Name { get; set; }
    /// <summary>
    /// To set an employee department
    /// </summary>
    string Dept { get; set; }
    /// <summary>
    /// To set an employee designation
    /// </summary>
    string Designation { get; set; }
 
    /// <summary>
    /// To display an employee details
    /// </summary>
    void DisplayDetails();
 
 
    /// <summary>
    ///Newly added for this example
    ///To set years of Experience       
    ///</summary>
    double Experience { get; set; }
    /// <summary>
    /// Newly added for this example
    /// </summary>
    /// <param name="visitor"></param>
    void Accept(IVisitor visitor);
}
/// <summary>
/// Leaf node
/// </summary>
class Employee : IEmployee
{
 
    /// <summary>
    ///
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    ///
    /// </summary>
    public string Dept { get; set; }
    /// <summary>
    ///
    /// </summary>
    public string Designation { get; set; }
    /// <summary>
    ///
    /// </summary>
    public double Experience { get; set; }
    /// <summary>
    /// Details of a leaf node
    /// </summary>
    public void DisplayDetails()
    {
        Console.WriteLine($"姓名:{Name} 工作在 {Dept} 部门.描述:{Designation}.经历 : {Experience} 年.");
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="visitor"></param>
    public void Accept(IVisitor visitor)
    {
        visitor.VisitEmployees(this);
    }
 
}
/// <summary>
/// Non-leaf node
/// </summary>
class CompositeEmployee : IEmployee
{
 
    /// <summary>
    ///
    /// </summary>
    public string Name { get; set; }
 
    /// <summary>
    ///
    /// </summary>
    public string Dept { get; set; }
    /// <summary>
    ///
    /// </summary>
    public string Designation { get; set; }
    /// <summary>
    ///
    /// </summary>
    public double Experience { get; set; }
 
    //The container for child objects
    //private List<IEmployee> subordinateList = new List<IEmployee>();
    //Making it public now
    /// <summary>
    ///
    /// </summary>
    public List<IEmployee> subordinateList = new List<IEmployee>();
 
    /// <summary>
    /// To add an employee
    /// </summary>
    /// <param name="e"></param>
    public void AddEmployee(IEmployee e)
    {
        subordinateList.Add(e);
    }
 
    /// <summary>
    /// To remove an employee
    /// </summary>
    /// <param name="e"></param>
    public void RemoveEmployee(IEmployee e)
    {
        subordinateList.Remove(e);
    }
 
    /// <summary>
    /// Details of a composite node
    /// </summary>
    public void DisplayDetails()
    {
        Console.WriteLine($"\n姓名:{Name} 工作在 {Dept} 部门.描述:{Designation}.经历 : {Experience} 年.");
        foreach (IEmployee e in subordinateList)
        {
            e.DisplayDetails();
        }
    }
 
    public void Accept(IVisitor visitor)
    {
        visitor.VisitEmployees(this);
    }
}
/// <summary>
/// Visitor interface   
/// </summary>
interface IVisitor
{
    //To visit leaf nodes
    void VisitEmployees(Employee employee);
 
    //To visit composite nodes
    void VisitEmployees(CompositeEmployee employee);
}
/// <summary>
/// Concrete visitor class-PromotionCheckerVisitor
/// </summary>
class PromotionCheckerVisitor : IVisitor
{
 
   /// <summary>
   ///
   /// </summary>
    string eligibleForPromotion = String.Empty;
    /// <summary>
    /// 工作经历大于15年
    /// </summary>
    /// <param name="employee"></param>
    public void VisitEmployees(CompositeEmployee employee)
    {
        //We'll promote them if experience is greater than 15 years
        eligibleForPromotion = employee.Experience > 15 ? "是" : "否";
        Console.WriteLine($"{employee.Name} 来自于 {employee.Dept} 工作长于15年是否有资格升职? :{eligibleForPromotion}");
 
    }
    /// <summary>
    /// 工作经历在于12年
    /// </summary>
    /// <param name="employee"></param>
    public void VisitEmployees(Employee employee)
    {
        //We'll promote them if experience is greater than 12 years
        eligibleForPromotion = employee.Experience > 12 ? "Yes" : "No";
        Console.WriteLine($"{employee.Name} 来自于 {employee.Dept} 工作长于12年是否有资格升职? :{eligibleForPromotion}");
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using DictType = Dictionary<Type, Action<Expression, StringBuilder>>;
   /// <summary>
   /// 访问者模式  Visitor Pattern
   /// geovindu,Geovin Du eidt   
   /// </summary>
   public abstract class Expression
   {
   }
   /// <summary>
   ///
   /// </summary>
   public class DoubleExpression : Expression
   {
 
       /// <summary>
       ///
       /// </summary>
       public double Value;
       /// <summary>
       ///
       /// </summary>
       /// <param name="value"></param>
       public DoubleExpression(double value)
       {
           Value = value;
       }
   }
   /// <summary>
   ///
   /// </summary>
   public class AdditionExpression : Expression
   {
       /// <summary>
       ///
       /// </summary>
       public Expression Left;
       /// <summary>
       ///
       /// </summary>
       public Expression Right;
       /// <summary>
       ///
       /// </summary>
       /// <param name="left"></param>
       /// <param name="right"></param>
       /// <exception cref="ArgumentNullException"></exception>
       public AdditionExpression(Expression left, Expression right)
       {
           Left = left ?? throw new ArgumentNullException(paramName: nameof(left));
           Right = right ?? throw new ArgumentNullException(paramName: nameof(right));
       }
   }
 
   /// <summary>
   ///
   /// </summary>
 
   public static class ExpressionPrinter
   {
       /// <summary>
       ///
       /// </summary>
       private static DictType actions = new DictType
       {
           [typeof(DoubleExpression)] = (e, sb) =>
           {
               var de = (DoubleExpression)e;
               sb.Append(de.Value);
           },
           [typeof(AdditionExpression)] = (e, sb) =>
           {
               var ae = (AdditionExpression)e;
               sb.Append("(");
               Print(ae.Left, sb);
               sb.Append("+");
               Print(ae.Right, sb);
               sb.Append(")");
           }
       };
       /// <summary>
       ///
       /// </summary>
       /// <param name="e"></param>
       /// <returns></returns>
       public static string Print3(this Expression e)
       {
           var sb = new StringBuilder();
           Print2(e, sb);
           return sb.ToString();
       }
       /// <summary>
       ///
       /// </summary>
       /// <param name="e"></param>
       /// <param name="sb"></param>
       private static void Print2(Expression e, StringBuilder sb)
       {
           actions[e.GetType()](e, sb);
       }
       /// <summary>
       ///
       /// </summary>
       /// <param name="e"></param>
       /// <param name="sb"></param>
       private static void Print(Expression e, StringBuilder sb)
       {
           if (e is DoubleExpression de)
           {
               sb.Append(de.Value);
           }
           else
           if (e is AdditionExpression ae)
           {
               sb.Append("(");
               Print(ae.Left, sb);
               sb.Append("+");
               Print(ae.Right, sb);
               sb.Append(")");
           }
           // breaks open-closed principle
           // will work incorrectly on missing case
       }
   }

  

调用:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//访问者模式
 Console.WriteLine("***访问者模式 Visitor Pattern with Composite Pattern Demo. ***");
 
 #region Mathematics department
 //2 lecturers work in Mathematics department
 Employee mathTeacher1 = new Employee { Name = "老大", Dept = "应用数学", Designation = "讲师" ,Experience=13.7};
 Employee mathTeacher2 = new Employee { Name = "老二", Dept = "应用数学", Designation = "讲师", Experience = 6.5 };
 
 //The college has a Head of Department in Mathematics
 CompositeEmployee hodMaths = new CompositeEmployee { Name = "老三", Dept = "数学", Designation = "数学系主任", Experience = 14 };
 
 //Lecturers of Mathematics directly reports to HOD-Maths
 hodMaths.AddEmployee(mathTeacher1);
 hodMaths.AddEmployee(mathTeacher2);
 #endregion
 
 #region Computer Science department
 //3 lecturers work in Computer Sc. department
 Employee cseTeacher1 = new Employee { Name = "老四", Dept = "计算机科学", Designation = "讲师", Experience = 10.2 };
 Employee cseTeacher2 = new Employee { Name = "老五", Dept = "计算机科学.", Designation = "讲师", Experience = 13.5 };
 Employee cseTeacher3 = new Employee { Name = "老六", Dept = "计算机科学", Designation = "讲师", Experience = 7.3 };
 
 //The college has a Head of Department in Computer science
 CompositeEmployee hodCompSc = new CompositeEmployee { Name = "老幺", Dept = "计算机科学.", Designation = "计算机科学系主任.", Experience = 16.5 };
 
 //Lecturers of Computer Sc. directly reports to HOD-CSE
 hodCompSc.AddEmployee(cseTeacher1);
 hodCompSc.AddEmployee(cseTeacher2);
 hodCompSc.AddEmployee(cseTeacher3);
 #endregion
 
 #region Top level management
 //The college also has a Principal
 CompositeEmployee principal = new CompositeEmployee { Name = "族长", Dept = "规划监督管理部门", Designation = "校长", Experience = 21 };
 
 //Head of Departments's of Maths and Computer Science directly reports to Principal.
 principal.AddEmployee(hodMaths);
 principal.AddEmployee(hodCompSc);
 #endregion
 
 /*
  * Printing the leaf-nodes and branches in the same way.
  * i.e. in each case, we are calling DisplayDetails() method.
 */          
 Console.WriteLine("\nDetails of a college structure is as follows:");
 //Prints the complete structure
 principal.DisplayDetails();           
 
 
 
 List<IEmployee> participants = new List<IEmployee>();
 
 //For employees who directly reports to Principal
 foreach (IEmployee e in principal.subordinateList)
 {
     // e.Accept(aVisitor);
     participants.Add(e);
 }
 //For employees who directly reports to HOD-Maths
 foreach (IEmployee e in hodMaths.subordinateList)
 {
     //e.Accept(aVisitor);
     participants.Add(e);
 }
 //For employees who directly reports to HOD-Comp.Sc
 foreach (IEmployee e in hodCompSc.subordinateList)
 {
     //e.Accept(aVisitor);
     participants.Add(e);
 }
 Console.WriteLine("\n***访问者模式 Visitor starts visiting our composite structure***\n");
 IVisitor visitor = new PromotionCheckerVisitor();
 /*
* Principal is already holding the highest position.
* We are not checking whether he is eligible
* for promotion or not.
*/
 //principal.Accept(visitor);
 //Visitor is traversing the participant list
 foreach ( IEmployee  emp in participants)
 {
     emp.Accept(visitor);
 }
 
 //
 var geovindu = new AdditionExpression(
left: new DoubleExpression(1),
right: new AdditionExpression(
left: new DoubleExpression(2),
 right: new DoubleExpression(3)));
 var sb = new StringBuilder();
 //ExpressionPrinter.Print2(e, sb);
 Console.WriteLine(geovindu.Print3());

  

 

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
***访问者模式 Visitor Pattern with Composite Pattern Demo. ***
 
Details of a college structure is as follows:
 
姓名:族长 工作在 规划监督管理部门 部门.描述:校长.经历 : 21 年.
 
姓名:老三 工作在 数学 部门.描述:数学系主任.经历 : 14 年.
姓名:老大 工作在 应用数学 部门.描述:讲师.经历 : 13.7 年.
姓名:老二 工作在 应用数学 部门.描述:讲师.经历 : 6.5 年.
 
姓名:老幺 工作在 计算机科学. 部门.描述:计算机科学系主任..经历 : 16.5 年.
姓名:老四 工作在 计算机科学 部门.描述:讲师.经历 : 10.2 年.
姓名:老五 工作在 计算机科学. 部门.描述:讲师.经历 : 13.5 年.
姓名:老六 工作在 计算机科学 部门.描述:讲师.经历 : 7.3 年.
 
***访问者模式 Visitor starts visiting our composite structure***
 
老三 来自于 数学 工作长于15年是否有资格升职? :否
老幺 来自于 计算机科学. 工作长于15年是否有资格升职? :是
老大 来自于 应用数学 工作长于12年是否有资格升职? :Yes
老二 来自于 应用数学 工作长于12年是否有资格升职? :No
老四 来自于 计算机科学 工作长于12年是否有资格升职? :No
老五 来自于 计算机科学. 工作长于12年是否有资格升职? :Yes
老六 来自于 计算机科学 工作长于12年是否有资格升职? :No
(1+(2+3))

  

posted @   ®Geovin Du Dream Park™  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示