设计模式之(行为型)解释器模式

94 阅读3分钟

解释器模式(Interpreter Pattern)是一种行为设计模式,用于定义一种语言的文法,并提供一个解释器来解释这种语言中的句子。它主要用于对特定问题的特定语言进行解析和执行。

关键概念

  1. 语言的文法:解释器模式将语言的语法规则和结构表示为一组类,每个类对应语言中的一个语法元素。这样,可以轻松扩展或修改语言的文法。
  2. 抽象表达式:定义一个抽象接口,所有的具体表达式都需要实现该接口。这个接口通常包含一个解释方法,用于根据给定的上下文进行解释。
  3. 终结符表达式:对应于语言中的基本元素(如变量、常量等),通常是没有子表达式的表达式。
  4. 非终结符表达式:由其他表达式组合而成的复杂表达式,例如运算符(如与、或、加、减等)。
  5. 上下文:解释器需要的环境,包含变量的值或其他必要的信息。

工作原理

解释器模式通过组合多个表达式对象来形成一个树形结构,从而可以表达复杂的语言句子。当需要解释某个句子时,调用根表达式的解释方法,该方法会递归调用其子表达式的解释方法,直到所有子表达式被解释为止。 下面是使用 C# 语言实现解释器模式来解析复杂计算公式的示例,类似于 SQL 中 WHERE 子句的条件解析。

解释器模式的 C# 实现

  1. 定义抽象表达式接口

    public interface IExpression
    {
        bool Interpret(Context context);
    }
    
  2. 定义终结符表达式

    • 变量表达式
    • 常量表达式
    public class Variable : IExpression
    {
        private string _name;
    
        public Variable(string name)
        {
            _name = name;
        }
    
        public bool Interpret(Context context)
        {
            return context.GetValue(_name);
        }
    }
    
    public class Constant : IExpression
    {
        private bool _value;
    
        public Constant(bool value)
        {
            _value = value;
        }
    
        public bool Interpret(Context context)
        {
            return _value;
        }
    }
    
  3. 定义非终结符表达式

    • 逻辑运算(与、或)
    • 比较运算(大于、小于、等于等)
    public class AndExpression : IExpression
    {
        private IExpression _left;
        private IExpression _right;
    
        public AndExpression(IExpression left, IExpression right)
        {
            _left = left;
            _right = right;
        }
    
        public bool Interpret(Context context)
        {
            return _left.Interpret(context) && _right.Interpret(context);
        }
    }
    
    public class OrExpression : IExpression
    {
        private IExpression _left;
        private IExpression _right;
    
        public OrExpression(IExpression left, IExpression right)
        {
            _left = left;
            _right = right;
        }
    
        public bool Interpret(Context context)
        {
            return _left.Interpret(context) || _right.Interpret(context);
        }
    }
    
    public class GreaterThanExpression : IExpression
    {
        private IExpression _left;
        private IExpression _right;
    
        public GreaterThanExpression(IExpression left, IExpression right)
        {
            _left = left;
            _right = right;
        }
    
        public bool Interpret(Context context)
        {
            return (int)_left.Interpret(context) > (int)_right.Interpret(context);
        }
    }
    
  4. 上下文类:提供变量的值。

    public class Context
    {
        private readonly Dictionary<string, int> _variables = new();
    
        public void Set(string key, int value)
        {
            _variables[key] = value;
        }
    
        public int GetValue(string key)
        {
            return _variables.TryGetValue(key, out int value) ? value : 0;
        }
    }
    
  5. 使用解析器

    • 创建表达式树并执行解析。
    public class Program
    {
        public static void Main(string[] args)
        {
            // 创建上下文
            var context = new Context();
            context.Set("age", 25);
            context.Set("salary", 5000);
    
            // 创建表达式:age > 20 AND salary > 3000
            IExpression expression = new AndExpression(
                new GreaterThanExpression(new Variable("age"), new Constant(20)),
                new GreaterThanExpression(new Variable("salary"), new Constant(3000))
            );
    
            // 解释表达式
            bool result = expression.Interpret(context);
            Console.WriteLine(result);  // 输出:True
        }
    }
    

小结

这个 C# 实现展示了如何使用解释器模式来解析复杂的计算公式,尤其是 SQL 中 WHERE 子句的条件。每个表达式都通过实现 IExpression 接口进行解释,可以根据需要自由组合,构建复杂的条件表达式。这个模式在动态生成查询条件时特别有用。