Mode interprète
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
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:
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:
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));
}
}
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