Une brève introduction aux modèles de conception Java: mode interpréteur

définition

Le modèle interpréteur est un modèle comportemental d'une classe. Étant donné une langue, le modèle interpréteur peut définir une représentation de sa grammaire et fournir un interprète en même temps. Le client peut utiliser cet interpréteur pour interpréter des phrases dans la langue.

intention

Étant donné une langue, définir sa représentation grammaticale et définir un interprète, cet interprète utilise l'identifiant pour interpréter des phrases dans la langue

Résoudre principalement le problème

Construire un interpréteur pour expliquer des phrases pour une grammaire fixe

Avantages et inconvénients

avantage:

  • Bonne évolutivité et flexibilité
  • Ajout d'une nouvelle façon d'interpréter les expressions
  • Facile à mettre en œuvre une grammaire simple

Désavantages:

  • Moins de scénarios d'utilisation
  • Plus difficile à maintenir pour une grammaire complexe
  • Provoquera une expansion de classe
  • Utilisation de la méthode d'appel récursive, faible efficacité

structure

Insérez la description de l'image ici
Rôles impliqués:

  • Rôle d'expression abstraite (Expression): Déclarez une interface abstraite que tous les rôles d'expression concrète doivent implémenter. Cette interface est principalement une méthode d'interprétation, appelée opération d'interprétation
  • Rôle TerminalExpression (TerminalExpression): il s'agit d'un rôle spécifique
    • Implémentation de l'interface requise par le rôle d'expression abstraite, principalement une méthode d'interprétation
    • Chaque symbole terminal de la grammaire a une expression terminale spécifique qui lui correspond
  • Rôle Expression Nonterminal (NonterminalExpression): il s'agit d'un rôle spécifique
    • Chaque règle de la grammaire R = R1R2 ... Rn nécessite une classe d'expression non terminale spécifique
    • Chaque symbole dans R = R1R2 ... Rn contient une variable d'instance de type statique Expression
    • Implémentez la méthode d'interprétation de l'opération d'interprétation, et l'opération d'interprétation appelle de manière récursive les variables d'instance mentionnées ci-dessus représentant les symboles dans R1R2 ... Rn
  • Rôle client: créer un arbre de syntaxe abstraite, appeler des opérations d'interprétation
  • Rôle de contexte: Fournissez des informations globales en dehors de l'interpréteur, telles que la vraie valeur des variables, etc.

Exemple

Rôle d'expression abstraite:

/**
 * 这个抽象类代表终结类和非终结类的抽象化
 */
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();
}

Rôle d'expression de fin:
Insérez la description de l'image ici
un objet Constant représente une constante booléenne

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 objet Variable représente une variable nommée

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;
    }
}

Rôle d'expression non-terminal:
Insérez la description de l'image ici
représente l'opération consistant à donner une nouvelle expression booléenne par opération ET logique de deux expressions booléennes:

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() + ")";
    }
}

Représente l'opération consistant à donner une nouvelle expression booléenne par une opération OR logique par deux expressions booléennes:

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() + ")";
    }
}

Représente l'opération d'une nouvelle expression booléenne donnée par une expression booléenne via la négation logique:

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 classe d'environnement définit un mappage des variables aux valeurs booléennes:

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();
    }
}

Rôle du client:

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));
    }
}

Insérez la description de l'image ici

Situation applicable

  • Le système a un langage simple pour expliquer
  • Certains problèmes récurrents peuvent être exprimés dans ce langage simple
  • L'efficacité n'est pas la principale considération

Je suppose que tu aimes

Origine blog.csdn.net/qq_34365173/article/details/108559975
conseillé
Classement