深入Java设计模式之释器模式

简介: 深入Java设计模式之释器模式

介绍

意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

主要解决:对于一些固定文法构建一个解释句子的解释器。

何时使用:如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

如何解决:构建语法树,定义终结符与非终结符。

关键代码:构建环境类,包含解释器之外的一些全局信息,一般是 HashMap。

应用实例:编译器、运算表达式计算。

优点: 1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。

缺点: 1、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 4、解释器模式采用递归调用方法。

使用场景: 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。 2、一些重复出现的问题可以用一种简单的语言来进行表达。 3、一个简单语法需要解释的场景。

注意事项:可利用场景比较少,JAVA 中如果碰到可以用 expression4J 代替。

案例

package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class ClientForFinanceDemo
{
    public static void main(String[] args)
    {
        String expStr = getExpStr();
        HashMap<String, Integer> var = getValue(expStr);
        Calculator calculator = new Calculator(expStr);
        System.out.println("运算结果为:" + expStr + " = " + calculator.run(var));
    }
    public static String getExpStr()
    {
        String in = null;
        System.out.println("请输入表达式:");
        try
        {
            in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
        } catch (IOException exception)
        {
            exception.printStackTrace();
        }
        return in;
    }
    public static HashMap<String, Integer> getValue(String expStr)
    {
        String in = null;
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for (char ch : expStr.toCharArray())
        {
            if (ch != '+' && ch != '-')
            {
                if (!map.containsKey(String.valueOf(ch)))
                {
                    System.out.print("请输入" + ch + "的值:");
                    try
                    {
                        in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    } catch (IOException exception)
                    {
                        exception.printStackTrace();
                    }
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }
        return map;
    }
}

 

package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
import java.util.HashMap;
import java.util.Stack;
public class Calculator
{
    private Expression expression;
    public Calculator(String expStr)
    {
        Stack<Expression> stack = new Stack<Expression>();
        char[] charArray = expStr.toCharArray();
        Expression left = null;
        Expression right = null;
        for (int i = 0; i < charArray.length; i++)
        {
            switch (charArray[i])
            {
                case '+':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default:
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
            }
        }
        this.expression = stack.pop();
    }
    public int run(HashMap<String, Integer> var)
    {
        return this.expression.interpreter(var);
    }
}

表达式接口

package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
import java.util.HashMap;
public abstract class Expression
{
    public abstract int interpreter(HashMap<String, Integer> var);
}

运算符号

package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
public abstract class SymbolExpression extends Expression
{
    protected Expression left;
    protected Expression right;
    public SymbolExpression(Expression left, Expression right)
    {
        this.left = left;
        this.right = right;
    }
}
package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
import java.util.HashMap;
public class SubExpression extends SymbolExpression
{
    public SubExpression(Expression left, Expression right)
    {
        super(left, right);
    }
    public int interpreter(HashMap<String, Integer> var)
    {
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}

变量

package com.lzhsite.technology.designPattern.Interpreter.FinanceDemo;
import java.util.HashMap;
public class VarExpression extends Expression
{
    private String key;
    public VarExpression(String key)
    {
        this.key = key;
    }
    public int interpreter(HashMap<String, Integer> var)
    {
        return var.get(this.key);
    }
}

示例代码:

https://gitee.com/lzhcode/maven-parent/tree/master/lzh-technology/src/main/java/com/lzhsite/technology/designPattern/Interpreter/FinanceDemo


目录
相关文章
|
2月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
142 11
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
25天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
88 40
|
26天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
54 19
|
24天前
|
设计模式 Java
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
52 12
|
26天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
45 15
|
3月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
3月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
56 4
|
3月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式