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)) |
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
分类:
CSharp code
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!