In the book "Java and Patterns" of Dr. Shanhong, this describes the interpreter (interpreter) Pattern:
The interpreter pattern is the behavior pattern of the class. Given a language, the interpreter pattern can define a representation of its grammar and provide an interpreter at the same time. The client can use this interpreter to interpret the sentences in the language.
structure of the interpreter pattern
The following is an example of a schematic system that discusses the structure of the interpreter pattern. The structure diagram of the system is as follows:
The roles involved in the pattern are as follows:
(1) Abstract expression role: declares an abstract interface that all specific expression roles need to implement. This interface is primarily a interpret () method, which is called an interpretation operation.
(2) The Terminator expression (Terminal expression) role: implements the interface required by the abstract expression role, mainly a interpret () method; each terminator in the grammar has a specific end expression corresponding to it. For example, there is a simple formula R=R1+R2, in which R1 and R2 are terminator, corresponding parsing R1 and R2 of the interpreter is the Terminator expression.
(3) Non-terminator expressions (nonterminal expression) role: Each rule in the grammar requires a specific non-terminator expression, the non-terminator expression is generally the operator in the grammar or other keywords, such as the formula R=R1+R2, "+ "is non-terminator, parsing" + "interpreter is a non-terminator expression.
(4) environment (context) Role: The task of this role is generally used to store the grammar of the individual terminator corresponding to the specific values, such as R=R1+R2, we give the R1 value of 100, to R2 assigned value 200. This information needs to be stored in the environment role, and in many cases it is sufficient for us to use map to act as an environment role.
To illustrate the implementation of the interpreter pattern, here is the simplest syntax and the implementation of the corresponding interpreter pattern, which is to manipulate and evaluate Boolean expressions in the simulated Java language.
In this language, Terminator is a Boolean variable, which is the constant true and false. Non-terminator expressions contain Boolean expressions such as operators and,or and not. This simple grammar is as follows:
Expression:: = Constant | Variable | Or | and | Not
And:: = Expression ' and ' expression
Or:: = expression ' or ' expression
Not:: = ' not ' Expression
Variable:: = any identifier
Constant:: = ' true ' | ' False '
The structure diagram for the interpreter pattern is as follows:
Source
Abstract expression Role
Public Abstract classExpression {/*** Based on the environment, this method interprets any given expression*/ Public Abstract Booleaninterpret (Context CTX); /*** Verify that two expressions are structurally identical*/ Public Abstract Booleanequals (Object obj); /*** Returns the hash code of an expression*/ Public Abstract inthashcode (); /*** Convert an expression to a string*/ Public AbstractString toString ();}
A constant object represents a Boolean constant
Public classConstantextendsexpression{Private Booleanvalue; PublicConstant (Booleanvalue) { This. Value =value; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofConstant) { return This. Value = =((Constant) obj). value; } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override Public Booleaninterpret (Context ctx) {returnvalue; } @Override PublicString toString () {return NewBoolean (value). toString (); } }
A variable object represents a well-known variable
Public classVariableextendsExpression {PrivateString name; PublicVariable (String name) { This. Name =name; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofVariable) { return This. Name.equals (((Variable) obj). Name); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override PublicString toString () {returnname; } @Override Public Booleaninterpret (Context ctx) {returnCtx.lookup ( This); }}
Represents the and class of the logical and operation, representing the operation of a new Boolean expression given by two Boolean expressions through the logical "and" Operation
Public classandextendsExpression {PrivateExpression left,right; Publicand (expression left, expression right) { This. left =Left ; This. right =Right ; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofand ) { returnLeft.equals (((and) obj). left) &&Right.equals (((and) obj). } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override Public Booleaninterpret (Context ctx) {returnLeft.interpret (CTX) &&Right.interpret (CTX); } @Override PublicString toString () {return"(" + left.tostring () + "and" + right.tostring () + ")"; }}
Represents the or class of a logical OR operation, representing the operation of a new Boolean expression given by a two Boolean expression by a logical OR operation
Public classOrextendsExpression {PrivateExpression left,right; PublicOr (expression left, expression right) { This. left =Left ; This. right =Right ; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofOr) { return This. Left.equals ((or) obj). left) && This. Right.equals (((Or) obj). right); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override Public Booleaninterpret (Context ctx) {returnLeft.interpret (CTX) | |Right.interpret (CTX); } @Override PublicString toString () {return"(" + left.tostring () + "OR" + right.tostring () + ")"; }}
The not class that represents the logical "not" operation, which represents the operation of a new Boolean expression given by a Boolean expression through a logical "non" operation
Public classNotextendsExpression {PrivateExpression exp; PublicNot (Expression exp) { This. Exp =exp; } @Override Public Booleanequals (Object obj) {if(obj! =NULL&& objinstanceofNot ) { returnExp.equals ((not) obj). exp); } return false; } @Override Public inthashcode () {return This. ToString (). Hashcode (); } @Override Public Booleaninterpret (Context ctx) {return!Exp.interpret (CTX); } @Override PublicString toString () {return"(not" + exp.tostring () + ")"; }}
The environment (context) class defines a mapping from a variable to a Boolean value
Public classContext {Privatemap<variable,boolean> map =NewHashmap<variable,boolean>(); Public voidAssign (Variable var,Booleanvalue) {Map.put (Var,NewBoolean (value)); } Public BooleanLookup (Variable var)throwsillegalargumentexception{Boolean Value=Map.get (VAR); if(Value = =NULL){ Throw Newillegalargumentexception (); } returnValue.booleanvalue (); }}
Client class
Public classClient { Public Static voidMain (string[] args) {Context ctx=NewContext (); Variable x=NewVariable ("X"); Variable y=NewVariable ("Y"); Constant C=NewConstant (true); Ctx.assign (x,false); Ctx.assign (Y,true); Expression Exp=NewOr (Newand (C,x),Newand (Y,NewNot (x))); System.out.println ("X=" +X.interpret (CTX)); System.out.println ("Y=" +Y.interpret (CTX)); System.out.println (exp.tostring ()+ "=" +Exp.interpret (CTX)); }}
The results of the operation are as follows:
The interpreter pattern for Java design patterns