设计模式-解释器模式

解释器模式

定义

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器可以使用该表示来解释这个句子。

结构

Context:环境类,它包含除解释器以外的全局信息。

AbstractExpression:抽象解释器类,定义一个实现类的接口。

TerminalExpression:终结符表达式类,实现与文法中的终结符相关联的解释操作。

NonTerminalExpression:非终结符表达式类。

类图

抽象表达式类:

public abstract class AbstractExpression {
	public abstract void interpreter(Context context);
}

环境类:

public class Context {
	private String input;

	public String getInput() {
		return input;
	}

	public void setInput(String input) {
		this.input = input;
	}

}

终结符表达式:

public class TerminalExpression extends AbstractExpression {

	@Override
	public void interpreter(Context context) {
		System.out.println("终端解释器");
	}

}

非终结符表达式类:

public class NonTerminalExpression extends AbstractExpression {

	@Override
	public void interpreter(Context context) {
		System.out.println("非终端解释器");
	}

}

测试类:

	public static void main(String[] args) {
		Context context = new Context();
		ArrayList<AbstractExpression> list = new ArrayList<AbstractExpression>();
		list.add(new TerminalExpression());
		list.add(new TerminalExpression());
		list.add(new NonTerminalExpression());
		list.add(new TerminalExpression());
		for (AbstractExpression expression : list) {
			expression.interpreter(context);
		}
	}

测试结果:

案例

我们都知道音乐是有乐谱的,根据乐谱可以演奏出动人的声音,那么乐谱是无法演奏的,必须通过音乐解释器将每个音符化成声音,乐谱分为音阶、音符、音速。本案例中音阶分为1、2、3档分别对应中高低音。音符分为C、D、E、F、G、A、B分别对应Do-Re-Mi-Fa-So-La-Ti。音速分为1、2、3档分别对应高中低速。

抽象表达式类:

public abstract class Expression {
	public void play(PlayContext context){
		/*
		 * 通过输入一串乐谱 O 2 E 0.5 C 1 D 0.5 T 1 F 1 O 3
		 * O 2 => 中音
		 * E 0.5 => Mi 0.5拍
		 * C 1 => Do 1拍
		 * D 0.5 => Re 0.5拍
		 * T 1 => 低速
		 * F 1 => Fa 1拍
		 * O 3 => 高音
		 */
		String text = context.getText();
		String key = text.substring(0, 1);
		text = text.substring(2);
		String value = "";
		if(text.indexOf(" ") > 0){
			value = text.substring(0,text.indexOf(" "));
			context.setText(text.substring(text.indexOf(" ")+1));
		}else{
			value = text.substring(0);
			context.setText("");
		}
		execute(key,value);
	}
	public abstract void execute(String key,String value);

}

环境类:

public class PlayContext {

	private String text;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
}

音符类:

public class Note extends Expression {

	@Override
	public void execute(String key, String value) {
		String note = "";
		switch (key) {
			case "C": note = "Do"; break;
			case "D": note = "Re"; break;
			case "E": note = "Mi"; break;
			case "F": note = "Fa"; break;
			case "G": note = "So"; break;
			case "A": note = "La"; break;
			case "B": note = "Ti"; break;
		}
		System.out.print(note);
	}


}

音阶类:

public class Step extends Expression{

	@Override
	public void execute(String key, String value) {
		String step = "";
		switch (value) {
			case "1": step = "低音"; break;
			case "2": step = "中音"; break;
			case "3": step = "高音"; break;
		}
		System.out.print(step);
	}

}

音速类:

public class Speed extends Expression{

	@Override
	public void execute(String key, String value) {
		String speed = "";
		switch (value) {
		case "1": speed = "低速"; break;
		case "2": speed = "中速"; break;
		case "3": speed = "高速"; break;
		}
		System.out.print(speed);
	}

}

测试类:

	public static void main(String[] args) {
		PlayContext context = new PlayContext();
		context.setText("O 2 E 0.5 C 1 D 0.5 T 1 F 1 O 3");
		Expression expression = null;
		while(context.getText().length() > 0){
			String tmp = context.getText().substring(0,1);
			switch (tmp) {
				case "O": expression = new Step(); break;
				case "T": expression = new Speed(); break;
				default:  expression = new Note(); break;
			}
			expression.play(context);
		}
	}

测试结果:

优点

可扩展性好,灵活方便,符合开闭原则,符合依赖倒转原则。

缺点

使用场景较少,并且解释器类使用递归调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值