设计模式 <行为型> | 解释器模式

解释器模式(Interpreter Pattern)

任何可以承载信息的载体,都可以称之为语言,语言如果想被理解,需要按照特定的语法去编排生成,解释器就是根据语法规则去解释语言。

结构图:

角色:

  1. 抽象表达式(Abstract Expression):声明解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  2. 终结符表达式(Terminal Expression):实现与语法中的元素相关联的解释操作,大多数情况下一个解释器模式中只有一个终结表达式,但有多个实例,对应不同的终结符。
  3. 非终结符表达式(Nonterminal Expression):语法中的每条规则对应于一个非终结表达式,非终结符表达式根据逻辑的复杂程度而增加,原则上每个语法规则都对应一个非终结符表达式
  4. 环境类(Context):用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。

适用场景:

  1. 日志、监控等分析场景下。

优点:

  1. 方便和扩展表示语言的语法,
  2. 每个语法规则对应一个类,符合单一原则。

缺点:

  1. 代码复杂度过高,继承过于复杂。
  2. 复杂表达式执行效率低。

代码(C#)

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

/// <summary>
/// 抽象表达式
/// </summary>
public interface IAbstractExpression
{
bool Interpret(string info);
}


/// <summary>
/// 终结符表达式
/// </summary>
public class TerminalExpression : IAbstractExpression
{
private List<string> ls = new List<string>();

public TerminalExpression(string[] data)
{
for (var i = 0; i < data.Length; i++)
{
ls.Add(data[i]);
}
}

public bool Interpret(string info)
{
if (ls.Contains(info))
{
return true;
}

return false;
}
}

/// <summary>
/// 非终结符表达式
/// </summary>
class NonterminalExpression : IAbstractExpression
{
private IAbstractExpression _cat;
private IAbstractExpression _dog;

public NonterminalExpression(IAbstractExpression cat, IAbstractExpression dog)
{
_cat = cat;
_dog = dog;
}

public bool Interpret(string str)
{
return _cat.Interpret(str) || _dog.Interpret(str);
}
}

/// <summary>
/// 环境
/// </summary>
public class MyContext
{
private string[] _cat = { "银渐层", "英短" };
private string[] _dog = { "金毛", "哈士奇" };
private IAbstractExpression _animal;

public MyContext()
{
IAbstractExpression cat = new TerminalExpression(_cat);
IAbstractExpression dog = new TerminalExpression(_dog);
_animal = new NonterminalExpression(cat, dog);
}

public void FreeRide(string info)
{
bool ok = _animal.Interpret(info);
if (ok)
{
Console.WriteLine($"{info},是宠物");
}
else
{
Console.WriteLine($"{info},不是宠物");
}
}
}

var myContext = new MyContext();
myContext.FreeRide("金毛");

最后

解释器模式的代码实现比较灵活,没有固定的模板。代码实现的核心思想,就是将语法解析的工作拆分到各个小类中,以此来避免大而全的解析类。一般的做法是,将语法规则拆分一些小的独立的单元,然后对每个单元进行解析,最终合并为对整个语法规则的解析。


设计模式 <行为型> | 解释器模式
http://example.com/posts/56322.html
作者
她微笑的脸y
发布于
2023年3月15日
许可协议