• CSharp: Visitor Pattern in donet core 3


        /// <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}");
            }
        }
    

      

     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
            }
        }
    

      

    调用:

               //访问者模式
                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());
    

      

    输出:

    ***访问者模式 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))
    

      

  • 相关阅读:
    【WPF】wpf image控件加载网络图片不显示问题,
    【VS】vs修改大小写快捷键
    【C#】菜单功能,将剪贴板JSON内容或者xml内容直接粘贴为类
    【异常】调用的目标发生了异常
    【MySQL】函数IFNULL、设置默认时间
    【Kindle】pdf转mobi适合kindle查看格式
    【WPF】中的文字修饰——上划线,中划线,基线与下划线
    vscode使用Eslint + prettier + beautify 格式化vue 代码不换行
    Office文件转PDF
    MSSQL同步刷新视图字段长度和源表保持一致
  • 原文地址:https://www.cnblogs.com/geovindu/p/16767461.html
Copyright © 2020-2023  润新知