Interpreter mode
The pattern we share with you today is the interpreter pattern.
First, explain what kind of problem the interpreter model is suitable to solve.
In fact, the problem with the interpreter pattern is that if a particular type of problem occurs on a high enough frequency, it may be worthwhile to express each instance of the problem as a simple language sentence. This allows you to build an interpreter that interprets the sentences to solve the problem.
In the case of an application, such as a regular expression is a specific application, the interpreter can define a grammar for regular representations, how to represent a particular regular expression, and how to interpret the regular expression.
The class structure diagram for the interpreter pattern is as follows.
The structure of the diagram is also better understood, the interpreter method abstracts a unified Interface (Abstractexpression), in need of interpretation of the content (context) to do understanding decoupling, call the specific interpreter method incoming content (context) to achieve the corresponding interpretation function.
So what's the benefit of the interpreter model?
In fact, using the interpreter pattern means that you can easily change and extend the grammar, because the pattern uses classes to represent the grammar rules, and you can use inheritance to change or extend the grammar. It is also easier to implement grammars because classes that define the nodes in the abstract syntax tree are generally similar, and these classes are easy to write directly.
In addition to the previous mentioned regular expression of this application, in fact, the usefulness is very wide, of course, the main or the interpretation of the text.
In addition to the benefits, the interpreter pattern is still inadequate, and the interpreter pattern defines at least one class for each rule in the grammar, so grammars that contain many rules may be difficult to manage and maintain. It is recommended that when the grammar is very complex, it is handled using other techniques such as a parser or compiler builder.
Said a lot, the following code to show a simple explanation of the concrete implementation of the model.
Realize
Note: All of the code in this article is compiled in an arc environment.
Context class Interface
Copy Code code as follows:
#import <Foundation/Foundation.h>
@interface Context:nsobject
@property NSString *input;
@property NSString *output;
@end
Context class implementation
Copy Code code as follows:
#import "Context.h"
@implementation context
@synthesize Input,output;
@end
Abstractexpression class Interface
Copy Code code as follows:
#import <Foundation/Foundation.h>
@class context;
@interface Abstractexpression:nsobject
-(void) interpret: (context*) context;
@end
Abstractexpression class implementation
Copy Code code as follows:
#import "AbstractExpression.h"
@implementation Abstractexpression
-(void) Interpret: (context *) context{
Return
}
@end
Terminalexpression class Interface
Copy Code code as follows:
#import "AbstractExpression.h"
@interface terminalexpression:abstractexpression
@end
Terminalexpression class implementation
Copy Code code as follows:
#import "TerminalExpression.h"
@implementation Terminalexpression
-(void) Interpret: (context *) context{
NSLog (@ "terminal interpreter");
}
@end
Nonterminalexpression class Interface
Copy Code code as follows:
#import "AbstractExpression.h"
@interface nonterminalexpression:abstractexpression
@end
Nonterminalexpression class implementation
Copy Code code as follows:
#import "NonterminalExpression.h"
@implementation Nonterminalexpression
-(void) Interpret: (context *) context{
NSLog (@ "Non-terminal interpreter");
}
@end
Main method call
Copy Code code as follows:
#import <Foundation/Foundation.h>
#import "Context.h"
#import "TerminalExpression.h"
#import "NonterminalExpression.h"
int main (int argc,const char * argv[])
{
@autoreleasepool {
Context *context = [[Contextalloc]init];
Nsmutablearray*list = [[Nsmutablearrayalloc]init];
[List Addobject:[[terminalexpressionalloc]init]];
[List Addobject:[[nonterminalexpressionalloc]init]];
[List Addobject:[[terminalexpressionalloc]init]];
[List Addobject:[[terminalexpressionalloc]init]];
For (abstractexpression *exp in list) {
[Exp Interpret:context];
}
}
return 0;
}
Well, the code above is just a simple show. The key is to apply it flexibly.
Summarize
The interpreter pattern belongs to the behavior pattern of the class, describes how to define a grammar for the language, how to represent a sentence in the language, and how to interpret the sentences, where the "language" is the code that uses the prescribed format and syntax. The interpreter mode is mainly used in compilers and is seldom used in the development of application systems.
Advantages:
1 easy to modify and expand the syntax.
2) easier to implement syntax.
Usage scenarios:
1 The grammar of the language is relatively simple.
2 efficiency is not the most important problem.