设计模式之 解释器模式

解释器模式(Interpreter Design Pattern),在我们开发中应用场景并不多,一般用在构建一种语言,对语法进行解释。例如用来实现编译器、正则、规则引擎等。

比如我们实现一个加减乘除的数字计算解析器,可以实现一个方法,方法内处理处理所有逻辑,但这种方法也只能实现简单的语法处理逻辑,如果我们将程序中的各种数学计算、逻辑计算等等算法都实现,那这个方法将变成一个庞大的方法,这样显然是不是一个好的实现。

代码例如这样:

int calculation(int num1, int num2, String calc) {
        if ("+".equals(calc)) {
            return num1+num2;
        } else if ("-".equals(calc)) {
            return num1-num2;
        } else if ("*".equals(calc)) {
            return num1*num2;
        } else if ("/".equals(calc)) {
            return num1/num2;
        } else if (......) {
           ......
        } ......
        //如果还有指数计算、开方计算、逻辑and-or-not计算等
        //那这里就需要写非常多的if-else,并且有非常多的实现逻辑
        return 0;
    }

这时解释器模式模式就派上用场了。

解释器模式,是将各种计算符号转换为类,将计算逻辑封装到各个类中,按照用户输入,匹配对应类,完成计算。

我们来看代码:

1、定义抽象解释器类,定义解释器行为

package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */
public interface Expression {
    long interpret();
}

2、实现具体解释器,解释器分两种,一种是数字,一种是计算符号

package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description: 数字
 */
public class NumberExpression implements Expression {
    private long number;

    public NumberExpression(long number){
        this.number = number;
    }

    public NumberExpression(String number){
        this.number = Long.parseLong(number);
    }

    @Override
    public long interpret() {
        return this.number;
    }
}
package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description: 加法
 */
public class AddExpression implements Expression {
    private Expression e1;
    private Expression e2;

    public AddExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    @Override
    public long interpret() {
        return e1.interpret()+e2.interpret();
    }
}
package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description: 减法
 */
public class SubExpression implements Expression {
    private Expression e1;
    private Expression e2;

    public SubExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    @Override
    public long interpret() {
        return e1.interpret()-e2.interpret();
    }
}
package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description: 乘法
 */
public class MultExpression implements Expression {
    private Expression e1;
    private Expression e2;

    public MultExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    @Override
    public long interpret() {
        return e1.interpret()*e2.interpret();
    }
}
package com.itzhimei.study.design.interpret;

/**
 * @Auther: www.itzhimei.com
 * @Description: 除法
 */
public class DivExpression implements Expression {
    private Expression e1;
    private Expression e2;

    public DivExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    @Override
    public long interpret() {
        return e1.interpret()/e2.interpret();
    }
}

3、测试:我们初始化了4个数字Expression,分别是1、2、3、4,用来计算加减乘除

package com.itzhimei.study.design.interpret;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: www.itzhimei.com
 * @Description:
 */
public class Client {

    public static void main(String[] args) {
        List<Expression> numExps = new ArrayList<>();
        for(int i=1; i<5; i++) {
            numExps.add(new NumberExpression(i));
        }
        Expression add = new AddExpression(numExps.get(0),numExps.get(1));
        System.out.println(numExps.get(0).interpret() +"+"+numExps.get(1).interpret() +"加法解释计算结果:"+add.interpret());

        Expression sub = new SubExpression(numExps.get(3),numExps.get(2));
        System.out.println(numExps.get(3).interpret() +"-"+numExps.get(2).interpret() +"减法解释计算结果:"+sub.interpret());

        Expression mult = new MultExpression(numExps.get(3),numExps.get(2));
        System.out.println(numExps.get(3).interpret() +"*"+numExps.get(2).interpret() +"乘法解释计算结果:"+mult.interpret());

        Expression div = new DivExpression(numExps.get(3),numExps.get(1));
        System.out.println(numExps.get(3).interpret() +"/"+numExps.get(1).interpret() +"除法解释计算结果:"+div.interpret());
    }
}

输出:

1+2加法解释计算结果:3
4-3减法解释计算结果:1
4*3乘法解释计算结果:12
4/2除法解释计算结果:2

类关系图: