Design Pattern - Interpreter(Java)

版权声明:欢迎转载并请注明出处,谢谢~~ https://blog.csdn.net/chimomo/article/details/81031095

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 

Definition

Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

Participants

    The classes and/or objects participating in this pattern are:

  • AbstractExpression (Expression)
    • Declares an interface for executing an operation
  • TerminalExpression (ThousandExpression, HundredExpression, TenExpression, OneExpression)
    • Implements an Interpret operation associated with terminal symbols in the grammar.
    • An instance is required for every terminal symbol in the sentence.
  • NonterminalExpression (not used)
    • One such class is required for every rule R ::= R1R2...Rn in the grammar
    • Maintains instance variables of type AbstractExpression for each of the symbols R1 through Rn.
    • Implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.
  • Context (Context)
    • Contains information that is global to the interpreter
  • Client (InterpreterApp)
    • Builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes
    • Invokes the Interpret operation

Sample Code in Java


This structural code demonstrates the Interpreter patterns, which using a defined grammar, provides the interpreter that processes parsed statements.

/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.sample;

/**
 * The 'AbstractExpression' abstract class.
 *
 * @author Chimomo
 */
abstract class AbstractExpression {

    /**
     * Interpret.
     *
     * @param context
     */
    public abstract void interpret(Context context);

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.sample;

/**
 * The 'Context' class.
 *
 * @author Chimomo
 */
class Context {
}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.sample;

/**
 * The 'NonterminalExpression' class.
 *
 * @author Chimomo
 */
class NonterminalExpression extends AbstractExpression {

    /**
     * Interpret.
     *
     * @param context
     */
    @Override
    public void interpret(Context context) {
        System.out.println("Called Nonterminal.interpret()");
    }

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.sample;

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

/**
 * Startup class for Structural Interpreter Design Pattern.
 *
 * @author Chimomo
 */
class Program {

    /**
     * Entry point into console application.
     *
     * @param args
     */
    public static void main(String[] args) {
        Context context = new Context();

        // Usually a tree.
        List<AbstractExpression> list = new ArrayList<>();
        list.add(new TerminalExpression());
        list.add(new NonterminalExpression());
        list.add(new TerminalExpression());
        list.add(new TerminalExpression());

        // Interpret.
        for (AbstractExpression exp : list) {
            exp.interpret(context);
        }
    }

}

/*
Output:
Called Terminal.interpret()
Called Nonterminal.interpret()
Called Terminal.interpret()
Called Terminal.interpret()
 */
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.sample;

/**
 * The 'TerminalExpression' class.
 *
 * @author Chimomo
 */
class TerminalExpression extends AbstractExpression {

    /**
     * Interpret.
     *
     * @param context
     */
    @Override
    public void interpret(Context context){
        System.out.println("Called Terminal.interpret()");
    }

}

This real-world code demonstrates the Interpreter pattern which is used to convert a Roman numeral to a decimal.

/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'Context' class.
 *
 * @author Chimomo
 */
class Context {

    // The input.
    String input;

    // The output.
    int output;

    /**
     * Initializes a new instance of the "Context" class.
     *
     * @param input
     */
    public Context(String input) {
        this.input = input;
    }

    /**
     * Get input.
     *
     * @return
     */
    public String getInput() {
        return this.input;
    }

    /**
     * Set input.
     *
     * @param input
     */
    public void setInput(String input) {
        this.input = input;
    }

    /**
     * Get output.
     *
     * @return
     */
    public int getOutput() {
        return this.output;
    }

    /**
     * Set output.
     *
     * @param output
     */
    public void setOutput(int output) {
        this.output = output;
    }

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'AbstractExpression' abstract class.
 *
 * @author Chimomo
 */
abstract class Expression {

    /**
     * The five.
     *
     * @return
     */
    public abstract String five();

    /**
     * The four.
     *
     * @return
     */
    public abstract String four();

    /**
     * Interpret.
     *
     * @param context
     */
    public void interpret(Context context) {
        if (context.getInput().length() == 0) {
            return;
        }

        if (context.getInput().startsWith(this.nine())) {
            context.setOutput(context.getOutput() + 9 * this.multiplier());
            context.setInput(context.getInput().substring(2));
        } else if (context.getInput().startsWith(this.four())) {
            context.setOutput(context.getOutput() + 4 * this.multiplier());
            context.setInput(context.getInput().substring(2));
        } else if (context.getInput().startsWith(this.five())) {
            context.setOutput(context.getOutput() + 5 * this.multiplier());
            context.setInput(context.getInput().substring(1));
        }

        while (context.getInput().startsWith(this.one())) {
            context.setOutput(context.getOutput() + 1 * this.multiplier());
            context.setInput(context.getInput().substring(1));
        }
    }

    /**
     * The multiplier.
     *
     * @return
     */
    public abstract int multiplier();

    /**
     * The nine.
     *
     * @return
     */
    public abstract String nine();

    /**
     * The one.
     *
     * @return
     */
    public abstract String one();

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'TerminalExpression' class.
 * Hundred checks C, CD, D or CM.
 *
 * @author Chimomo
 */
class HundredExpression extends Expression {

    /**
     * The five.
     *
     * @return
     */
    @Override
    public String five() {
        return "D";
    }

    /**
     * The four.
     *
     * @return
     */
    @Override
    public String four() {
        return "CD";
    }

    /**
     * The multiplier.
     *
     * @return
     */
    @Override
    public int multiplier() {
        return 100;
    }

    /**
     * The nine.
     *
     * @return
     */
    public String nine() {
        return "CM";
    }

    /**
     * The one.
     *
     * @return
     */
    @Override
    public String one() {
        return "C";
    }

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'TerminalExpression' class.
 * One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX.
 *
 * @author Chimomo
 */
class OneExpression extends Expression {

    /**
     * The five.
     *
     * @return
     */
    @Override
    public String five() {
        return "V";
    }

    /**
     * The four.
     *
     * @return
     */
    @Override
    public String four() {
        return "IV";
    }

    /**
     * The multiplier.
     *
     * @return
     */
    @Override
    public int multiplier() {
        return 1;
    }

    /**
     * The nine.
     *
     * @return
     */
    public String nine() {
        return "IX";
    }

    /**
     * The one.
     *
     * @return
     */
    @Override
    public String one() {
        return "I";
    }

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

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

/**
 * Startup class for Real-World Interpreter Design Pattern.
 *
 * @author Chimomo
 */
class Program {

    /**
     * Entry point into console application.
     *
     * @param args Arguments
     */
    public static void main(String[] args) {
        String roman = "MCMXXVIII";
        Context context = new Context(roman);

        // Build the 'parse tree'.
        List<Expression> tree = new ArrayList<>();
        tree.add(new ThousandExpression());
        tree.add(new HundredExpression());
        tree.add(new TenExpression());
        tree.add(new OneExpression());

        // Interpret.
        for (Expression exp : tree) {
            exp.interpret(context);
        }

        System.out.println(String.format("%s = %s", roman, context.output));
    }

}

/*
Output:
MCMXXVIII = 1928
 */
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'TerminalExpression' class.
 * Ten checks for X, XL, L and XC.
 *
 * @author Chimomo
 */
class TenExpression extends Expression {

    /**
     * The five.
     *
     * @return
     */
    @Override
    public String five() {
        return "L";
    }

    /**
     * The four.
     *
     * @return
     */
    @Override
    public String four() {
        return "XL";
    }

    /**
     * The multiplier.
     *
     * @return
     */
    @Override
    public int multiplier() {
        return 10;
    }

    /**
     * The nine.
     *
     * @return
     */
    public String nine() {
        return "XC";
    }

    /**
     * The one.
     *
     * @return
     */
    @Override
    public String one() {
        return "X";
    }

}
/*
 *  Chimomo's Blog: https://blog.csdn.net/chimomo/
 */
package chimomo.learning.java.designpattern.interpreter.realworld;

/**
 * The 'TerminalExpression' class.
 * Thousand checks for the Roman Numeral M.
 *
 * @author Chimomo
 */
class ThousandExpression extends Expression {

    /**
     * The five.
     *
     * @return
     */
    @Override
    public String five() {
        return " ";
    }

    /**
     * The four.
     *
     * @return
     */
    @Override
    public String four() {
        return " ";
    }

    /**
     * The multiplier.
     *
     * @return
     */
    @Override
    public int multiplier() {
        return 1000;
    }

    /**
     * The nine.
     *
     * @return
     */
    public String nine() {
        return " ";
    }

    /**
     * The one.
     *
     * @return
     */
    @Override
    public String one() {
        return "M";
    }

}

猜你喜欢

转载自blog.csdn.net/chimomo/article/details/81031095