美文网首页
设计模式之解释器模式

设计模式之解释器模式

作者: Kevin_小飞象 | 来源:发表于2019-04-04 11:24 被阅读0次

定义

给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。(其中语言就是我们需要解释的对象,文法就是这个语言的规律,解释器就是翻译机,通过文法来翻译语言。)

Android中源码使用解释器模式

  • PackageParser
    PackageParser 是对 AndroidManifest.xml 配置文件进行读取。

特点

  • 优点
    最大的优点使其灵活的扩展性,当我们想对文法规则进行扩展延伸时,只需要增加相应的非终结符解释器,并在构建抽象语法树时,使用到新增的解释器对象进行具体的解释即可,非常方便。

  • 缺点
    1.每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。
    2.解释器模式由于使用了大量的循环和递归,效率是个问题,特别是用于解析复杂、冗长的语法时,效率是难以忍受的。

使用场景

1.如果某个简单的语言需要解释执行而且可以将该语言中的语句表示为一个抽象的语法树时可以考虑使用解释器模式。
2.在某些特定的领域出现不断重复的问题时,可以将该领域的问题转化为一种语法规则下的语句,然后构建解释器来解释该语句。

简单实现

需求:输入一个模型公式(加减四则运算),然后输入模型中的参数,运算出结果。

/**
 * Created on 2019/4/4 10:57
 * 抽象的算数运算解释器
 * @author Scarf Gong
 */
public abstract class AirthemticExpression {
    public abstract int interpreter();
}

---------------------------------
/**
 * Created on 2019/4/4 10:59
 * 数字解释器
 * @author Scarf Gong
 */
public class NumExpression extends AirthemticExpression {
    private int num;

    public NumExpression(int num) {
        this.num = num;
    }

    @Override
    public int interpreter() {
        return num;
    }
}

---------------------------------
/**
 * Created on 2019/4/4 11:01
 * 运算符解释器
 * @author Scarf Gong
 */
public abstract class OperatorExpression extends AirthemticExpression {

    public AirthemticExpression exp1,exp2;

    public OperatorExpression(AirthemticExpression exp1, AirthemticExpression exp2) {
        this.exp1 = exp1;
        this.exp2 = exp2;
    }
}

---------------------------------
/**
 * Created on 2019/4/4 11:03
 *  加法
 * @author Scarf Gong
 */
public class AdditionExpression extends OperatorExpression {
    public AdditionExpression(AirthemticExpression exp1, AirthemticExpression exp2) {
        super(exp1, exp2);
    }

    @Override
    public int interpreter() {
        return exp1.interpreter() + exp2.interpreter();
    }
}

---------------------------------
/**
 * Created on 2019/4/4 11:03
 * 减法
 * @author Scarf Gong
 */
public class SubtractionExpression extends OperatorExpression {
    public SubtractionExpression(AirthemticExpression exp1, AirthemticExpression exp2) {
        super(exp1, exp2);
    }

    @Override
    public int interpreter() {
        return exp1.interpreter() - exp2.interpreter();
    }
}

处理解释器:

/**
 * Created on 2019/4/4 11:06
 * 处理解释器
 * @author Scarf Gong
 */
public class Calculator {
    //声明一个Stack栈储存并操作所有相关的解释器
    private Stack<AirthemticExpression> mStack = new Stack<>();

    public Calculator(String expression) {
        AirthemticExpression exp1,exp2;

        String[] elements = expression.split(" ");

        for(int i = 0; i < elements.length; i++){
            switch (elements[i].charAt(0)) {
                case '+':
                    //如果是加号,则将栈中的解释器弹出作为运算符号左边的解释器
                    exp1 = mStack.pop();
                    //同时将运算符号数组下标的下一个元素构造为一个数字解释器
                    exp2 = new NumExpression(Integer.parseInt(elements[++i]));
                    //通过上面的两个数字解释器构造加法运算解释器
                    mStack.push(new AdditionExpression(exp1, exp2));
                    break;

                case '-':
                    exp1 = mStack.pop();

                    exp2 = new NumExpression(Integer.parseInt(elements[++i]));
                    mStack.push(new SubtractionExpression(exp1, exp2));
                    break;

                default:
                    /*
                     * 如果为数字,直接构造数字解释器并压入栈
                     */
                    mStack.push(new NumExpression(Integer.valueOf(elements[i])));
                    break;
            }
        }

    }

    public int calculate() {
        return mStack.pop().interpreter();
    }
}

使用:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
    }

    private void initData() {
        Calculator calculator = new Calculator("22 + 334 + 443 + 13");
        Log.d("TAG", "结果: " + calculator.calculate());

        Calculator c = new Calculator("334 - 43 + 13");
        Log.d("TAG", "结果: " + c.calculate());
    }
}

结果:

2019-04-04 11:17:41 D/TAG: 结果: 812
2019-04-04 11:17:41 D/TAG: 结果: 304

相关文章

网友评论

      本文标题:设计模式之解释器模式

      本文链接:https://www.haomeiwen.com/subject/yfhfiqtx.html