El principio del modo de intérprete y su reflejo en el código fuente de JDK
- Descripción general de la serie de patrones de diseño
- Prefacio
- Que es el modo intérprete
- Expresión terminal y expresión no terminal
- Ejemplo de modo de intérprete
- Rol del modo intérprete
- El modo de intérprete se aplica en el código fuente JDK y Spring
- Escenarios de aplicación del modo de intérprete
- Ventajas y desventajas del modo intérprete
- para resumir
Descripción general de la serie de patrones de diseño
Patrones de diseño | Boleto aereo |
---|---|
Tres modelos de fábrica | Entrada de embarque |
Modo de estrategia | Entrada de embarque |
Modo de delegación | Entrada de embarque |
Patrón de método de plantilla | Entrada de embarque |
Modo observador | Entrada de embarque |
Modo singleton | Entrada de embarque |
Modo de prototipo | Entrada de embarque |
Modelo de agencia | Entrada de embarque |
Modo decorador | Entrada de embarque |
Modo adaptador | Entrada de embarque |
Modo constructor | Entrada de embarque |
Modelo de cadena de responsabilidad | Entrada de embarque |
Modelo de peso mosca | Entrada de embarque |
Modo de combinación | Entrada de embarque |
Patrón de fachada | Entrada de embarque |
Modo Puente | Entrada de embarque |
Modelo intermediario | Entrada de embarque |
Modo iterador | Entrada de embarque |
Modo de estado | Entrada de embarque |
Modo intérprete | Entrada de embarque |
Modo de nota | Entrada de embarque |
Modo de comando | Entrada de embarque |
Modo visitante | Entrada de embarque |
Resumen de 7 principios y patrones de diseño de diseño de software | Entrada de embarque |
Prefacio
El modo de intérprete significa literalmente que necesitas explicar el significado de algún contenido, pero de hecho esto es exactamente lo que hace el modo de intérprete. Este artículo presentará principalmente el principio del patrón de intérprete, y combinará un ejemplo simple para profundizar nuestra comprensión del patrón de intérprete El patrón de intérprete ya tiene muchas ruedas en nuestra capa de desarrollo de aplicaciones, por lo que reduciremos el número de repeticiones. Haz ruedas.
Que es el modo intérprete
El patrón de intérprete se refiere a un idioma dado, se define una representación de su gramática (como: expresiones de suma, resta, multiplicación y división, expresiones regulares, etc.), y luego se define un intérprete, que se usa para interpretar Nuestra representación gramatical (expresión).
El modo de intérprete es un modo de diseño que se analiza de acuerdo con la gramática prescrita (gramática), que es un modo de comportamiento.
De acuerdo, el momento de fingir ha llegado de nuevo: hablar es barato, mostrarle el código , primero veamos un ejemplo muy simple.
Expresión terminal y expresión no terminal
Hay dos conceptos de expresión terminal y expresión no terminal en el modo de intérprete.
- Expresión terminal (Expresión terminal): realiza la operación de interpretación relacionada con el símbolo terminal en la gramática. Cada símbolo terminal en la gramática tiene una expresión terminal específica correspondiente. Por ejemplo, en nuestra operación R = M + N, M y N son símbolos terminales, y el intérprete correspondiente que analiza M y N es la expresión terminal.
- Expresión no terminal (expresión no terminal): realice las operaciones de interpretación relacionadas con los símbolos no terminales en la gramática. Cada regla de la gramática corresponde a una expresión no terminal. Las expresiones no terminales son generalmente operadores o palabras clave en la gramática, como se muestra arriba: el signo "+" en R = M + N es un símbolo no terminal y el intérprete que analiza el signo "+" es una expresión no terminal .
Ejemplo de modo de intérprete
A continuación, escribiremos un ejemplo simple con una clase de expresión de suma y resta simple:
1. Primero, establezca una interfaz de expresión de nivel superior:
package com.zwx.design.pattern.interpreter;
public interface IExpression {
int interpret();
}
2. Defina una expresión abstracta no terminal (como los signos más y menos son expresiones no terminales):
package com.zwx.design.pattern.interpreter;
/**
* 非终结表达式-抽象表达式
*/
public abstract class AbstractNonTerminalExpression implements IExpression{
protected IExpression leftExpression;
protected IExpression rightExpression;
public AbstractNonTerminalExpression(IExpression leftExpression, IExpression rightExpression) {
this.leftExpression = leftExpression;
this.rightExpression = rightExpression;
}
}
3. Debido a que este ejemplo solo enumera la suma y la resta, también necesitamos una clase de suma y una clase de resta:
package com.zwx.design.pattern.interpreter;
/**
* 非终结表达式-具体表达式-加法表达式
*/
public class AddExpression extends AbstractNonTerminalExpression {
public AddExpression(IExpression leftExpression, IExpression rightExpression) {
super(leftExpression, rightExpression);
}
@Override
public int interpret() {
return this.leftExpression.interpret() + this.rightExpression.interpret();
}
}
package com.zwx.design.pattern.interpreter;
/**
* 非终结表达式-具体表达式-减法表达式
*/
public class SubExpression extends AbstractNonTerminalExpression {
public SubExpression(IExpression leftExpression, IExpression rightExpression) {
super(leftExpression, rightExpression);
}
@Override
public int interpret() {
return this.leftExpression.interpret() - this.rightExpression.interpret();
}
}
4. Cree una expresión final (como el valor en la suma y la resta):
package com.zwx.design.pattern.interpreter;
/**
* 终结表达式-数值表达式
*/
public class NumberExpression implements IExpression{
private int value;
public NumberExpression(String value) {
this.value = Integer.valueOf(value);
}
@Override
public int interpret() {
return this.value;
}
}
5. Finalmente, también necesitamos información contextual para almacenar los resultados de nuestros cálculos:
package com.zwx.design.pattern.interpreter;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class ExpressionContext {
private Integer currValue;//记录当前运算结果,空表示暂未运算
private Stack<IExpression> stack = new Stack<>();
public ExpressionContext(String expression) {
this.parse(expression);
}
private void parse(String expression) {
String[] elementArr = expression.split(" ");
for (int i=0;i<elementArr.length;i++){
String element = elementArr[i];
if (element.equals("+")){
IExpression leftExpression = stack.pop();//栈内元素出栈
IExpression rightExpression = new NumberExpression(elementArr[++i]);//取出+号后的下一个元素
IExpression addExpression = new AddExpression(leftExpression,rightExpression);
stack.push(new NumberExpression(addExpression.interpret() + ""));//将计算结果入栈
}else if (element.equals("-")){
IExpression leftExpression = stack.pop();//栈内元素出栈
IExpression rightExpression = new NumberExpression(elementArr[++i]);//取出-号后的下一个元素
IExpression subExpression = new SubExpression(leftExpression,rightExpression);
stack.push(new NumberExpression(subExpression.interpret() + ""));//将计算结果入栈
}else{
stack.push(new NumberExpression(element));//如果是数字则直接入栈
}
}
}
public int calcuate(){
return stack.pop().interpret();//经过前面解析,到这里stack内只会剩下唯一一个数字,即运算结果
}
}
6. Finalmente, cree una nueva clase de prueba para probar:
package com.zwx.design.pattern.interpreter;
public class TestInterpreter {
public static void main(String[] args) {
ExpressionContext context = new ExpressionContext("666 + 888 - 777");
System.out.println(context.calcuate());
context = new ExpressionContext("123 - 456 + 11");
System.out.println(context.calcuate());
}
}
El resultado de ejecución es:
777
-322
Rol del modo intérprete
Del ejemplo anterior, podemos concluir que el modo de intérprete tiene principalmente 4 roles:
- Expresión abstracta (Expresión): generalmente, se define un método de interpretación y la forma de analizarlo se implementará mediante subclases (como IExpression en el ejemplo).
- Expresión terminal (expresión terminal): realice la operación de interpretación relacionada con el símbolo terminal en la gramática (como AddExpression, SubExpression en el ejemplo).
- Expresión no terminal: implemente operaciones de interpretación relacionadas con símbolos no terminales en la gramática (como NumberExpression en el ejemplo).
- Contexto: contiene información global fuera del intérprete. Generalmente se usa para almacenar el valor específico correspondiente a cada símbolo de terminal en la gramática.
El modo de intérprete se aplica en el código fuente JDK y Spring
Todos deberían poder adivinar la aplicación de esto en el código fuente, como la expresión regular en la clase JDK: Pattern. También existe la interfaz ExpressionParse en Spring. No sé si ha usado esta expresión en Spring. De hecho, también puede realizar sumas, restas, multiplicaciones y divisiones. El siguiente es un ejemplo de aplicación simple:
como mencionamos al principio, generalmente usamos relativamente poco este modo de intérprete en el desarrollo comercial, y algunas expresiones comunes se han analizado directamente para nosotros. Úselo, a menos que estemos involucrados en un desarrollo de bajo nivel y necesitemos definir expresiones más complejas.
Escenarios de aplicación del modo de intérprete
El modo de intérprete se puede utilizar principalmente en los siguientes escenarios:
- 1. Cuando tenemos algunos problemas que necesitan un análisis repetido, podemos considerar definir una expresión para expresar.
- 2. Si necesita explicar algo de gramática simple, también puede considerar el modo de intérprete.
Ventajas y desventajas del modo intérprete
ventaja:
- 1. La escalabilidad es relativamente fuerte. Como se puede ver en nuestro ejemplo anterior, cada una de nuestras expresiones es una clase, por lo que si necesita modificar una regla determinada, solo necesita modificar la clase de expresión correspondiente.Puede agregar una nueva clase al expandir. Arriba.
Desventaja
- 1. Cuando las reglas gramaticales son más complicadas, provocará una expansión de la clase, que es más difícil de mantener.
- 2. Cuando las reglas gramaticales son más complicadas, si algo sale mal, la depuración es más difícil.
- 3. La eficiencia de ejecución es relativamente baja. Porque cuando la expresión es más complicada, el resultado se analizará de forma recursiva si el resultado tiene capas.
para resumir
Este artículo presenta principalmente el uso básico del patrón de intérprete y utiliza un ejemplo simple para ayudar a comprender mejor el patrón de intérprete. Por supuesto, este ejemplo es relativamente simple de escribir y no se consideran muchas lógicas de negocios, pero estos no son el tema central de este artículo. , El enfoque de este artículo es presentar la idea del modo de intérprete. Finalmente, también presentamos la incorporación del modo de intérprete en el código fuente relevante de JDK. Espero que a través de este artículo, pueda tener una comprensión más profunda de las ideas de diseño del modo de intérprete.
Por favor, prestame atención y aprende y progresa con el lobo solitario .