Una breve introducción a los patrones de diseño de Java: modo de intérprete

definición

El modelo de intérprete es un modelo de comportamiento de una clase. Dado un idioma, el modelo de intérprete puede definir una representación de su gramática y proporcionar un intérprete al mismo tiempo. El cliente puede utilizar este intérprete para interpretar oraciones en el idioma.

intención

Dado un idioma, define su representación gramatical y define un intérprete, este intérprete utiliza el identificador para interpretar oraciones en el idioma.

Principalmente resuelve el problema

Construir un intérprete para explicar oraciones para una gramática fija.

Pros y contras

ventaja:

  • Buena escalabilidad y flexibilidad
  • Se agregó una nueva forma de interpretar expresiones.
  • Fácil de implementar gramática simple

Desventajas:

  • Escenarios de menor uso
  • Más difícil de mantener para gramática compleja
  • Causará expansión de clases
  • Usando el método de llamada recursiva, baja eficiencia

estructura

Inserte la descripción de la imagen aquí
Roles involucrados:

  • Rol de expresión abstracta (expresión): declare una interfaz abstracta que todos los roles de expresión concretos deben implementar. Esta interfaz es principalmente un método de interpretación, llamado operación de interpretación
  • Rol TerminalExpression (TerminalExpression): este es un rol específico
    • Implementó la interfaz requerida por el rol de expresión abstracta, principalmente un método de interpretación
    • Cada símbolo terminal en la gramática tiene una expresión terminal específica correspondiente.
  • Rol Nonterminal Expression (NonterminalExpression): este es un rol específico
    • Cada regla en la gramática R = R1R2 ... Rn requiere una clase de expresión no terminal específica
    • Cada símbolo en R = R1R2 ... Rn contiene una variable de instancia de tipo estático Expresión
    • Implemente el método de interpretación de la operación de interpretación, y la operación de interpretación llama de forma recursiva a las variables de instancia mencionadas anteriormente que representan los símbolos en R1R2 ... Rn
  • Rol del cliente: construir un árbol de sintaxis abstracto, operaciones de interpretación de llamadas
  • Rol de contexto: proporcione información global fuera del intérprete, como el valor real de las variables, etc.

Ejemplo

Rol de expresión abstracta:

/**
 * 这个抽象类代表终结类和非终结类的抽象化
 */
public abstract class Expression {
    
    

    /** 以环境类为准,本方法解释给定的任何一个表达式 */
    public abstract boolean interpret(Context ctx);

    /** 检验两个表达式在结构上是否相同 */
    public abstract boolean equals(Object o);

    /** 返回表达式的hashCode */
    public abstract int hashCode();

    /** 将表达式转换为字符串 */
    public abstract String toString();
}

Rol de expresión final:
Inserte la descripción de la imagen aquí
un objeto constante representa una constante booleana

public class Constant extends Expression {
    
    
    private boolean value;

    public Constant(boolean value) {
    
    
        this.value = value;
    }

    /** 解释操作 */
    @Override
    public boolean interpret(Context ctx) {
    
    
        return value;
    }

    /** 检验两个表达式在结构上是否相同 */
    @Override
    public boolean equals(Object o) {
    
    
        if (o != null && o instanceof Constant) {
    
    
            return this.value = ((Constant)o).value;
        }
        return false;
    }

    /** 返回表达式的hashCode */
    @Override
    public int hashCode() {
    
    
        return (this.toString()).hashCode();
    }

    /** 将表达式转换为字符串 */
    @Override
    public String toString(){
    
    
        return new Boolean(value).toString();
    }
}

Un objeto Variable representa una variable nombrada

public class Variable extends Expression {
    
    

    private String name;

    public Variable(String name) {
    
    
        this.name = name;
    }

    /** 解释操作 */
    @Override
    public boolean interpret(Context ctx) {
    
    
        return ctx.lookup(this);
    }

    /** 检验两个表达式在结构上是否相同 */
    @Override
    public boolean equals(Object o) {
    
    
        if (o != null && o instanceof Variable) {
    
    
            return this.name.equals(((Variable)o).name);
        }
        return false;
    }

    /** 返回表达式的hashCode */
    @Override
    public int hashCode() {
    
    
        return (this.toString()).hashCode();
    }

    /** 将表达式转换为字符串 */
    @Override
    public String toString() {
    
    
        return name;
    }
}

Rol de expresión no terminal:
Inserte la descripción de la imagen aquí
representa la operación de dar una nueva expresión booleana mediante la operación lógica Y de dos expresiones booleanas:

public class And extends Expression {
    
    

    private Expression left, right;

    public And(Expression left, Expression right) {
    
    
        this.left = left;
        this.right = right;
    }

    /** 解释操作 */
    @Override
    public boolean interpret(Context ctx) {
    
    
        return left.interpret(ctx) && right.interpret(ctx);
    }

    /** 检验两个表达式在结构上是否相同 */
    @Override
    public boolean equals(Object o) {
    
    
        if (o != null && o instanceof And) {
    
    
            return this.left.equals(((And)o).left) && this.right.equals(((And)o).right);
        }
        return false;
    }

    /** 返回表达式的hashCode */
    @Override
    public int hashCode() {
    
    
        return (this.toString()).hashCode();
    }

    /** 将表达式转换为字符串 */
    @Override
    public String toString() {
    
    
        return "(" + left.toString() + " AND " + right.toString() + ")";
    }
}

Representa la operación de dar una nueva expresión booleana mediante la operación lógica OR mediante dos expresiones booleanas:

public class Or extends Expression {
    
    

    private Expression left, right;

    public Or(Expression left, Expression right) {
    
    
        this.left = left;
        this.right = right;
    }

    /** 解释操作 */
    @Override
    public boolean interpret(Context ctx) {
    
    
        return left.interpret(ctx) || right.interpret(ctx);
    }

    /** 检验两个表达式在结构上是否相同 */
    @Override
    public boolean equals(Object o) {
    
    
        if (o != null && o instanceof Or) {
    
    
            return this.left.equals(((Or)o).left) && this.right.equals(((Or)o).right);
        }
        return false;
    }

    /** 返回表达式的hashCode */
    @Override
    public int hashCode() {
    
    
        return (this.toString()).hashCode();
    }

    /** 将表达式转换为字符串 */
    @Override
    public String toString() {
    
    
        return "(" + left.toString() + " OR " + right.toString() + ")";
    }
}

Representa la operación de una nueva expresión booleana dada por una expresión booleana mediante negación lógica:

public class Not extends Expression {
    
    

    private Expression exp;

    public Not(Expression exp) {
    
    
        this.exp = exp;
    }

    /** 解释操作 */
    @Override
    public boolean interpret(Context ctx) {
    
    
        return !exp.interpret(ctx);
    }

    /** 检验两个表达式在结构上是否相同 */
    @Override
    public boolean equals(Object o) {
    
    
        if (o != null && o instanceof Not) {
    
    
            return this.exp.equals(((Not)o).exp);
        }
        return false;
    }

    /** 返回表达式的hashCode */
    @Override
    public int hashCode() {
    
    
        return (this.toString()).hashCode();
    }

    /** 将表达式转换为字符串 */
    @Override
    public String toString() {
    
    
        return "(Not " + exp.toString() + ")";
    }
}

La clase de entorno define un mapeo de variables a valores booleanos:

public class Context {
    
    

    private HashMap map = new HashMap();

    public void assign(Variable var, boolean value) {
    
    
        map.put(var, new Boolean(value));
    }

    public boolean lookup(Variable var) {
    
    
        Boolean value = (Boolean) map.get(var);
        if (value == null) {
    
    
            throw  new IllegalArgumentException();
        }
        return value.booleanValue();
    }
}

Rol del cliente:

public class Client {
    
    
    private static Context ctx;
    private static Expression exp;

    public static void main(String[] args) {
    
    
        ctx = new Context();
        Variable x = new Variable("x");
        Variable y = new Variable("y");
        Constant c = new Constant(true);
        ctx.assign(x, false);
        ctx.assign(y, true);
        exp = new Or(new And(c, x), new And(y, new Not(x)));
        System.out.println("x= " + x.interpret(ctx));
        System.out.println("y= " + y.interpret(ctx));
        System.out.println(exp.toString() + " = " + exp.interpret(ctx));
    }
}

Inserte la descripción de la imagen aquí

Situación aplicable

  • El sistema tiene un lenguaje sencillo para explicar
  • Algunos problemas recurrentes se pueden expresar en este sencillo lenguaje.
  • La eficiencia no es la consideración principal

Supongo que te gusta

Origin blog.csdn.net/qq_34365173/article/details/108559975
Recomendado
Clasificación