一、概述
給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
二、适用性
當有一個語言需要解釋執行,并且你可将該語言中的句子表示為一個抽象文法樹時,可使 用解釋器模式。而當存在以下情況時該模式效果最好:
- 該文法簡單對于複雜的文法,文法的類層次變得龐大而無法管理。
- 效率不是一個關鍵問題最高效的解釋器通常不是通過直接解釋文法分析樹實作的,而是首先将它們轉換成另一種形式。
三、參與者
- AbstractExpression(抽象表達式) 聲明一個抽象的解釋操作,這個接口為抽象文法樹中所有的節點所共享。
- TerminalExpression(終結符表達式) 實作與文法中的終結符相關聯的解釋操作。一個句子中的每個終結符需要該類的一個執行個體。
- NonterminalExpression(非終結符表達式) 為文法中的非終結符實作解釋(Interpret)操作。
- Context(上下文) 包含解釋器之外的一些全局資訊。
- Client(用戶端) 建構(或被給定)表示該文法定義的語言中一個特定的句子的抽象文法樹。該抽象文法樹由NonterminalExpression和TerminalExpression的執行個體裝配而成。調用解釋操作。
四、類圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicGcq5SYlJDMhBzM2MTN1UjZ4ImYwEDO0M2MxUzNzIzMiJWZk9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.jpg)
五、示例
- AbstractExpression
package com.lyz.design.interpreter;
/**
* AbstractExpression
* @author binghe
*
*/
public abstract class Expression {
abstract void interpret(Context ctx);
}
- Expression
AdvanceExpression
package com.lyz.design.interpreter;
/**
* Expression
* @author binghe
*
*/
public class AdvanceExpression extends Expression {
void interpret(Context ctx) {
System.out.println("這是進階解析器!");
}
}
SimpleExpression
package com.lyz.design.interpreter;
/**
* Expression
* @author binghe
*
*/
public class SimpleExpression extends Expression {
void interpret(Context ctx) {
System.out.println("這是普通解析器!");
}
}
- Context
package com.lyz.design.interpreter;
import java.util.ArrayList;
import java.util.List;
/**
* Context
* @author binghe
*
*/
public class Context {
private String content;
private List<Expression> list = new ArrayList<Expression>();
public void setContent(String content) {
this.content = content;
}
public String getContent() {
return this.content;
}
public void add(Expression eps) {
list.add(eps);
}
public List<Expression> getList() {
return list;
}
}
- Test
package com.lyz.design.interpreter;
/**
* Text
* @author binghe
*
*/
public class Test {
public static void main(String[] args) {
Context ctx = new Context();
ctx.add(new SimpleExpression());
ctx.add(new AdvanceExpression());
ctx.add(new SimpleExpression());
for (Expression eps : ctx.getList()) {
eps.interpret(ctx);
}
}
}