首页 > 其他分享 >CSharp: Interpreter Pattern in donet core 3

CSharp: Interpreter Pattern in donet core 3

时间:2022-10-12 23:11:44浏览次数:41  
标签:core Pattern new emp2 emp3 emp1 Employee Interpreter public

 

 /// <summary>
    ///  解释器模式 Interpreter Pattern
    ///  geovindu, Geovin Du edit
    /// </summary>
    interface Employee
    {
        /// <summary>
        /// 是否解释
        /// </summary>
        /// <param name="context">输入背景</param>
        /// <returns></returns>
        bool Interpret(Context context);
    }
    /// <summary>
    /// IndividualEmployee class
    /// 单独雇员
    /// </summary>
    class IndividualEmployee : Employee
    {
        /// <summary>
        /// 年经验
        /// </summary>
        private int yearOfExperience;
        /// <summary>
        /// 当前等级
        /// </summary>
        private string currentGrade;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="experience">经验年数</param>
        /// <param name="grade">等级</param>
        public IndividualEmployee(int experience, string grade)
        {
            this.yearOfExperience = experience;
            this.currentGrade = grade;
        }
        /// <summary>
        /// 是否解释
        /// </summary>
        /// <param name="context">输入背景</param>
        /// <returns></returns>
        public bool Interpret(Context context)
        {
            if (this.yearOfExperience >= context.GetYearofExperience()
                 && context.GetPermissibleGrades().Contains(this.currentGrade))
            {
                return true;
            }
            return false;
        }
    }
    /// <summary>
    /// OrExpression class
    /// 或经验
    /// </summary>
    class OrExpression : Employee
    {
        private Employee emp1;
        private Employee emp2;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="emp1">输入雇员</param>
        /// <param name="emp2">输入雇员</param>
        public OrExpression(Employee emp1, Employee emp2)
        {
            this.emp1 = emp1;
            this.emp2 = emp2;
        }
        /// <summary>
        /// 是否解释
        /// </summary>
        /// <param name="context">输入背景</param>
        /// <returns></returns>
        public bool Interpret(Context context)
        {
            return emp1.Interpret(context) || emp2.Interpret(context);
        }
    }
    /// <summary>
    /// AndExpression class
    /// 添加经验
    /// </summary>
    class AndExpression : Employee
    {
        private Employee emp1;
        private Employee emp2;

        /// <summary>
        /// 添加经验
        /// </summary>
        /// <param name="emp1">输入雇员</param>
        /// <param name="emp2">输入雇员</param>
        public AndExpression(Employee emp1, Employee emp2)
        {
            this.emp1 = emp1;
            this.emp2 = emp2;
        }
        /// <summary>
        /// 是否解释
        /// </summary>
        /// <param name="context">输入背景</param>
        /// <returns></returns>
        public bool Interpret(Context context)
        {
            return emp1.Interpret(context) && emp2.Interpret(context);
        }
    }
    /// <summary>
    /// NotExpression class
    /// 没有经验
    /// </summary>
    class NotExpression : Employee
    {
        private Employee emp;

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="expr">输入雇员</param>
        public NotExpression(Employee expr)
        {
            this.emp = expr;
        }
        /// <summary>
        /// 是否解释
        /// </summary>
        /// <param name="context">输入背景</param>
        /// <returns></returns>
        public bool Interpret(Context context)
        {
            return !emp.Interpret(context);
        }
    }
    /// <summary>
    /// Context class
    ///背景
    /// </summary>
    class Context
    {
        /// <summary>
        /// 晋升所需的经验
        /// </summary>
        private int experienceReqdForPromotion;
        /// <summary>
        /// 允许成绩列表
        /// </summary>
        private List<string> allowedGrades;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="experience">经验年数</param>
        /// <param name="allowedGrades">允许成绩列表</param>
        public Context(int experience, List<string> allowedGrades)
        {
            this.experienceReqdForPromotion = experience;
            this.allowedGrades = new List<string>();
            foreach (string grade in allowedGrades)
            {
                this.allowedGrades.Add(grade);
            }
        }
        /// <summary>
        /// 赋值经验年数
        /// </summary>
        /// <returns></returns>
        public int GetYearofExperience()
        {
            return experienceReqdForPromotion;
        }
        /// <summary>
        /// 赋值允许的成绩
        /// </summary>
        /// <returns></returns>
        public List<string> GetPermissibleGrades()
        {
            return allowedGrades;
        }
    }
    /// <summary>
    /// EmployeeBuilder class
    /// </summary>
    class EmployeeBuilder
    {
        // Building the tree
        //Complex Rule-1: emp1 and (emp2 or (emp3 or emp4))
        /// <summary>
        /// 创建规则
        /// </summary>
        /// <param name="emp1"></param>
        /// <param name="emp2"></param>
        /// <param name="emp3"></param>
        /// <param name="emp4"></param>
        /// <returns></returns>
        public Employee BuildTreeBasedOnRule1(Employee emp1, Employee emp2, Employee emp3, Employee emp4)
        {
            // emp3 or emp4
            Employee firstPhase = new OrExpression(emp3, emp4);
            // emp2 or (emp3 or emp4)
            Employee secondPhase = new OrExpression(emp2, firstPhase);
            // emp1 and (emp2 or (emp3 or emp4))
            Employee finalPhase = new AndExpression(emp1, secondPhase);
            return finalPhase;
        }
        //Complex Rule-2: emp1 or (emp2 and (not emp3 ))

        /// <summary>
        /// 创建规则
        /// </summary>
        /// <param name="emp1"></param>
        /// <param name="emp2"></param>
        /// <param name="emp3"></param>
        /// <returns></returns>
        public Employee BuildTreeBasedOnRule2(Employee emp1, Employee emp2, Employee emp3)
        {
            // Not emp3
            Employee firstPhase = new NotExpression(emp3);
            // emp2 or (not emp3)
            Employee secondPhase = new AndExpression(emp2, firstPhase);
            // emp1 and (emp2 or (not emp3 ))
            Employee finalPhase = new OrExpression(emp1, secondPhase);
            return finalPhase;
        }
    }

  

   /// <summary>
    ///  解释器模式 Interpreter Pattern
    ///  geovindu, Geovin Du edit
    /// </summary>
    public interface IElement
    {
        int Value { get; }
    }
    /// <summary>
    /// 
    /// </summary>
    public class Integer : IElement
    {
        public Integer(int value)
        {
            Value = value;
        }

        public int Value { get; }
    }
    /// <summary>
    /// 
    /// </summary>
    public class BinaryOperation : IElement
    {
        public enum Type
        {
            Addition,
            Subtraction
        }

        public Type MyType;
        public IElement Left, Right;

        public int Value
        {
            get
            {
                switch (MyType)
                {
                    case Type.Addition:
                        return Left.Value + Right.Value;
                    case Type.Subtraction:
                        return Left.Value - Right.Value;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public class Token
    {
        public enum Type
        {
            Integer, Plus, Minus, Lparen, Rparen
        }

        public Type MyType;
        public string Text;

        public Token(Type type, string text)
        {
            MyType = type;
            Text = text;
        }

        public override string ToString()
        {
            return $"`{Text}`";
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public class GevovinDu
    {
        public static List<Token> Lex(string input)
        {
            var result = new List<Token>();

            for (int i = 0; i < input.Length; i++)
            {
                switch (input[i])
                {
                    case '+':
                        result.Add(new Token(Token.Type.Plus, "+"));
                        break;
                    case '-':
                        result.Add(new Token(Token.Type.Minus, "-"));
                        break;
                    case '(':
                        result.Add(new Token(Token.Type.Lparen, "("));
                        break;
                    case ')':
                        result.Add(new Token(Token.Type.Rparen, ")"));
                        break;
                    default:
                        var sb = new StringBuilder(input[i].ToString());
                        for (int j = i + 1; j < input.Length; ++j)
                        {
                            if (char.IsDigit(input[j]))
                            {
                                sb.Append(input[j]);
                                ++i;
                            }
                            else
                            {
                                result.Add(new Token(Token.Type.Integer, sb.ToString()));
                                break;
                            }
                        }
                        break;
                }
            }

            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tokens"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public  static IElement Parse(IReadOnlyList<Token> tokens)
        {
            var result = new BinaryOperation();
            bool haveLHS = false;
            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                // look at the type of token
                switch (token.MyType)
                {
                    case Token.Type.Integer:
                        var integer = new Integer(int.Parse(token.Text));
                        if (!haveLHS)
                        {
                            result.Left = integer;
                            haveLHS = true;
                        }
                        else
                        {
                            result.Right = integer;
                        }
                        break;
                    case Token.Type.Plus:
                        result.MyType = BinaryOperation.Type.Addition;
                        break;
                    case Token.Type.Minus:
                        result.MyType = BinaryOperation.Type.Subtraction;
                        break;
                    case Token.Type.Lparen:
                        int j = i;
                        for (; j < tokens.Count; ++j)
                            if (tokens[j].MyType == Token.Type.Rparen)
                                break; // found it!
                                       // process subexpression w/o opening
                        var subexpression = tokens.Skip(i + 1).Take(j - i - 1).ToList();
                        var element = Parse(subexpression);
                        if (!haveLHS)
                        {
                            result.Left = element;
                            haveLHS = true;
                        }
                        else result.Right = element;
                        i = j; // advance
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            return result;
        }
    }

  

调用:

            //解释器模式 
            Console.WriteLine("*** 解释器模式 Interpreter Pattern Demonstration-2***\n");

            // Minimum Criteria for promoton is:
            // The year of experience is minimum 10 yrs. and 
            // Employee grade should be either G2 or G3
            List<string> allowedGrades = new List<string> { "G2", "G3" };
            Context context = new Context(10, allowedGrades);
            Employee emp1 = new IndividualEmployee(5, "G1");
            Employee emp2 = new IndividualEmployee(10, "G2");
            Employee emp3 = new IndividualEmployee(15, "G3");
            Employee emp4 = new IndividualEmployee(20, "G4");

            EmployeeBuilder builder = new EmployeeBuilder();

            //Validating the 1st complex rule
            Console.WriteLine("----- 验证第一个复杂规则.-----");
            Console.WriteLine("emp1和emp2、emp3、emp4中的任何一个是否有资格晋升?"
                + builder.BuildTreeBasedOnRule1(emp1, emp2, emp3, emp4).Interpret(context));
            Console.WriteLine("emp2和emp1、emp3、emp4中的任何一个是否有资格晋升?"
                + builder.BuildTreeBasedOnRule1(emp2, emp1, emp3, emp4).Interpret(context));
            Console.WriteLine("emp3和emp1、emp2、emp3中的任何一个是否有资格晋升?"
                + builder.BuildTreeBasedOnRule1(emp3, emp1, emp2, emp4).Interpret(context));
            Console.WriteLine("emp4和emp1、emp2、emp3中的任何一个是否有资格晋升?"
                + builder.BuildTreeBasedOnRule1(emp4, emp1, emp2, emp3).Interpret(context));

            Console.WriteLine("-----现在验证第二个复杂的规则.-----");
            //Validating the 2nd complex rule
            Console.WriteLine("emp1或(emp2而不是emp3)是否有资格晋升?"
                + builder.BuildTreeBasedOnRule2(emp1, emp2, emp3).Interpret(context));
            Console.WriteLine("emp2或(emp3但不是emp4)是否有资格晋升?"
                + builder.BuildTreeBasedOnRule2(emp2, emp3, emp4).Interpret(context));

            Console.WriteLine();

            var input = "(13+4)-(12+1)";
            var tokens = GevovinDu.Lex(input);
            Console.WriteLine(string.Join("\t", tokens));

            var parsed = GevovinDu.Parse(tokens);
            Console.WriteLine($"{input} = {parsed.Value}");

  

输出:

***?解释器模式 Interpreter Pattern Demonstration-2***

----- 验证第一个复杂规则.-----
emp1和emp2、emp3、emp4中的任何一个是否有资格晋升?False
emp2和emp1、emp3、emp4中的任何一个是否有资格晋升?True
emp3和emp1、emp2、emp3中的任何一个是否有资格晋升?True
emp4和emp1、emp2、emp3中的任何一个是否有资格晋升?False
-----现在验证第二个复杂的规则.-----
emp1或(emp2而不是emp3)是否有资格晋升?False
emp2或(emp3但不是emp4)是否有资格晋升?True

`(`     `13`    `+`     `4`     `)`     `-`     `(`     `12`    `+`     `1`     `)`
(13+4)-(12+1) = 4

  

 

标签:core,Pattern,new,emp2,emp3,emp1,Employee,Interpreter,public
From: https://www.cnblogs.com/geovindu/p/16786478.html

相关文章