解释器模式express
解释器模式就是定义一种语言,并定义这个语言的解释器,解释器可以按照定义好的语法来将这种语言‘翻译’成使用者能理解的语言。数组
普遍上来说,Java是一种定义的语言,JVM就是一种‘解释器’,而计算机就是最终的使用者。咱们写一段Java代码,而计算机只认识0101的机器语言,JVM就是将Java代码解释成0101的机器语言让计算机可以理解并运行。ide
咱们仍是以咱们实验室的实例来讲明下这个模式。this
最近咱们实验室的兽人工厂拿到了老总的一个批示:spa
class LaoZong { private String order = "MN1n2"; public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } } class ShouRenFactory { public void readOrder() { LaoZong lz = new LaoZong(); System.out.println(lz.getOrder()); } } public class Interpreter { public static void main(String[] args) { new ShouRenFactory().readOrder(); } }
因而兽人工厂拿到老板的指令就是"MN1n2"。彻底不明白要干什么,因而须要找老板秘书来解释下:翻译
class ShouRenFactory { public void readOrder() { LaoZong lz = new LaoZong(); MiShu ms = new MiShu(); System.out.println(ms.translate(lz.getOrder())); } } class MiShu { public String translate(String order) { //Black Box String realWord = "生产男兽人1个女兽人2个"; return realWord; } }
如今咱们兽人工厂终于知道了老总的命令:"生产男兽人1个女兽人2个", 可是秘书是怎么知道老总的命令的呢,若是兽人工厂也能知道秘书解析的过程,那就不用每次都麻烦秘书来解释了。毕竟秘书是老板用的,而不是兽人工厂用的。code
请教秘书解析的方法:blog
秘书说她先判断每个字幕或者数组是什么类型的命令,而后再用不一样的解释方法解释不一样的类型,好比说‘M’就是命令类的,‘Nn’是产品名称类的,数字就是数量类的。get
因而兽人工厂就根据秘书的方法实现了本身的解析方式:产品
public class Interpreter { public static void main(String[] args) { new ShouRenFactory().readOrder(); } } class ShouRenFactory { private String translate(String order) { String realOrder = ""; //组装解释器 List<Expression> expressions = new ArrayList<Expression>(); expressions.add(new CommandExpression()); expressions.add(new ProductExpression()); expressions.add(new NumberExpression()); //挨个解释老总的命令 String[] codes = order.split(""); for (String code :codes) { for (Expression expression : expressions) { if (expression.matches(code)) { realOrder += expression.excute(code); break; } } } return realOrder; } public void readOrder() { LaoZong lz = new LaoZong(); System.out.println(translate(lz.getOrder())); } } abstract class Expression { protected HashMap<String, String> map = new HashMap<String, String>(); private Set<String> getMarkers() { return map.keySet(); } public boolean matches(String code) { return getMarkers().contains(code); } abstract public String excute(String code); } class CommandExpression extends Expression { public CommandExpression() { map.put("M", "建立"); map.put("D", "销毁"); map.put("E", "维修"); } @Override public String excute(String code) { return map.get(code); } } class ProductExpression extends Expression { public ProductExpression() { map.put("N", "男兽人"); map.put("n", "女兽人"); } @Override public String excute(String code) { return map.get(code); } } class NumberExpression extends Expression { public NumberExpression() { } @Override public boolean matches(String code) { return code.matches("[0-9]"); } @Override public String excute(String code) { return code + "个"; } }
这样咱们就实现了一个简单的解析器模式,在这种模式下,咱们能够很简单的增长或者删除某种解析器。
解析器模式是一种易于理解但难于应用的模式。 除非在“一种特定类型的问题发生的频率足够高”的状况下,咱们并不推荐使用此模式。由于当文法特别复杂时,会产生不少类,这对维护来讲比较困难。总的来讲在文法比较简单且发生频率很高的状况下才使用此模式。