欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java解釋器模式

 更新時間:2021年10月14日 10:11:33   作者:KnightHONG  
這篇文章主要介紹了Java基于解釋器模式實(shí)現(xiàn)定義一種簡單的語言功能,簡單描述了解釋器模式的概念、功能及Java使用解釋器模式定義一種簡單語言的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下

​ **請注意!請注意?。?!**今天講給大家講解非?!?strong>有用”的設(shè)計(jì)模式,解釋器模式?。?!

​ 設(shè)計(jì)模式有三大種類,一種是創(chuàng)建型模式,一種是結(jié)構(gòu)型模式,最后一種是行為性模式,那么解釋器模式屬于哪一種呢?帶領(lǐng)大家一起來了解學(xué)習(xí)解釋器模式!

​ 本次介紹圍繞著以下五點(diǎn)展開。什么是解釋器模式?用來做什么?怎么做?有哪些優(yōu)點(diǎn)?有哪些不足?

​ 解釋器模式顧名思義,就是用來定義解釋。

​ 給定一種特定語言,這個語言有特定的文法,解釋器可以解釋這個語言中的句子含義。即解釋器提供一種語言,如java,同時它也提供一種手段去解析java語言寫出來的代碼。

​ 大家可能也會想到這就是類似編譯原理,一個算術(shù)表達(dá)式要經(jīng)過詞法分析,語法分析,構(gòu)建語法樹啥的;還有正則表達(dá)式;SQL解析,編譯器等等,其實(shí)都是解析式模式的一種實(shí)現(xiàn)。

​ 那怎么做?一個是說要有像編譯原理中的終結(jié)符非終結(jié)符,構(gòu)建一顆語法樹。同時需要有一個環(huán)境類,來管理輸入和輸出。

​ 這里我們舉一個例子,輸入一個表達(dá)式a+b-c+d-e,同時給這5個變量賦值,計(jì)算出它的值。那么使用解釋器模式要如何實(shí)現(xiàn)?

​ 我們?yōu)榻忉屍鞫x一個抽象解釋類Expression,所有的流轉(zhuǎn)通過interpreter方法實(shí)現(xiàn)。

​ 上下文管理輸入輸出使用一個HashMap去實(shí)現(xiàn)。

​ 定義符號解釋類SymbolExpression,加法解釋類AddExpreesion,減法解釋類SubExpression

類圖:

在這里插入圖片描述

具體代碼實(shí)現(xiàn):

public abstract class Expression {

    // map中攜帶了表達(dá)式中的變量名(key) 和 對應(yīng)的值(value)
    public abstract int interpreter(Map<String, Integer> var);

}

public class VarExpression extends Expression {

    // 表達(dá)式中對應(yīng)的變量名
    String key;

    public VarExpression(String var) {
        this.key = var;
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var.get(key);
    }
}

public class SymbolExpression extends Expression {

    // +或-符號 左右兩邊的表達(dá)式
    Expression var1;
    Expression var2;

    public SymbolExpression(Expression var1, Expression var2) {
        this.var1 = var1;
        this.var2 = var2;
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        // 實(shí)現(xiàn)抽象方法
        // 該類不需要用到該方法 默認(rèn)返回0
        return 0;
    }
}

public class AddExpression extends SymbolExpression {

    public AddExpression(Expression var1, Expression var2) {
        super(var1, var2);
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var1.interpreter(var) + var2.interpreter(var);
    }
}

public class SubExpression extends SymbolExpression {

    public SubExpression(Expression var1, Expression var2) {
        super(var1, var2);
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        return var1.interpreter(var) - var2.interpreter(var);
    }

}

public class Calculator {

    // 表達(dá)式
    private Expression expression;

    // 解析出表達(dá)式
    public Calculator(String expStr) {
        Stack<Expression> stack = new Stack<>();
        Expression left, right = null;
        char[] expStrCharArray = expStr.toCharArray();

        for(int i = 0; i < expStrCharArray.length; i++) {
            switch (expStrCharArray[i]) {
                case '+':// 加法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(expStrCharArray[++i]));
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':// 減法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(expStrCharArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default:// 表達(dá)式中的變量
                    stack.push(new VarExpression(String.valueOf(expStrCharArray[i])));
                    break;
            }
        }
        // 最后會獲得被Expression包裝起來的一個表達(dá)式
        this.expression = stack.pop();
    }

    // 計(jì)算結(jié)果
    public int run(Map<String, Integer> var) {
        return this.expression.interpreter(var);
    }
}

public class Client {

    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        Map<String, Integer> var = getValue(expStr);
        Calculator calculator = new Calculator(expStr);
        System.out.println("運(yùn)算結(jié)果:" + expStr + "=" + calculator.run(var));
    }

    //獲得表達(dá)式
    public static String getExpStr() {
        return "a+b-c+d-e";
    }

    //獲得值映射
    public static HashMap<String, Integer> getValue(String expStr) throws IOException {
        HashMap<String, Integer> map = new HashMap<>();

        for(char ch : expStr.toCharArray()) {
            if(ch != '+' && ch != '-' ) {
                if(! map.containsKey(String.valueOf(ch))) {
                    System.out.print("請輸入" + String.valueOf(ch) + "的值:");
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }

        return map;
    }

}


結(jié)果

/*
請輸入a的值:1
請輸入b的值:3
請輸入c的值:5
請輸入d的值:7
請輸入e的值:9
運(yùn)算結(jié)果:a+b-c+d-e=-3
*/

​ 或許看代碼會有點(diǎn)云里霧里,希望大家能手動敲一遍,或許會對整個過程有更進(jìn)一步的理解,在編碼的同時不斷思考,提升自我。

​ 很容易發(fā)現(xiàn)解釋器模式是屬于行為性模式的一種,這種模式更關(guān)注對象之間的通信。

​ 解釋器模式優(yōu)點(diǎn),結(jié)構(gòu)清晰,可拓展性好。但也有缺點(diǎn),一般用在比較底層場景,平常敲代碼可使用的場景比較少,并且解釋器模式采用的是遞歸的方式,當(dāng)語言比較長,性能不高;同時如果文法比較復(fù)雜,也需要更多的相應(yīng)解釋類。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • java實(shí)現(xiàn)清理DNS Cache的方法

    java實(shí)現(xiàn)清理DNS Cache的方法

    這篇文章主要介紹了java實(shí)現(xiàn)清理DNS Cache的方法,分析了幾種常用的清理方法,并給出了反射清理的完整實(shí)例,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象

    Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象

    這篇文章主要介紹了Java?Map.values()方法之如何獲取Map集合中的所有鍵值對象問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring定時任務(wù)輪詢本地?cái)?shù)據(jù)庫實(shí)現(xiàn)過程解析

    Spring定時任務(wù)輪詢本地?cái)?shù)據(jù)庫實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Spring定時任務(wù)輪詢本地?cái)?shù)據(jù)庫實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • SpringAOP如何獲取方法參數(shù)上的注解

    SpringAOP如何獲取方法參數(shù)上的注解

    這篇文章主要介紹了SpringAOP如何獲取方法參數(shù)上的注解操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringMvc入門指南(必看)

    SpringMvc入門指南(必看)

    下面小編就為大家?guī)硪黄猄pringMvc入門指南(必看)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • 詳解SpringBoot下文件上傳與下載的實(shí)現(xiàn)

    詳解SpringBoot下文件上傳與下載的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot下文件上傳與下載的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java8?Stream流多字段求和、匯聚的實(shí)例

    Java8?Stream流多字段求和、匯聚的實(shí)例

    這篇文章主要介紹了Java8?Stream流多字段求和、匯聚的實(shí)例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法

    spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法

    本篇文章主要介紹了spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Java中增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理和坑詳解

    Java中增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理和坑詳解

    增強(qiáng)的for循環(huán)是在傳統(tǒng)的for循環(huán)中增加的強(qiáng)大的迭代功能的循環(huán),是在jdk1.5之后提出來的。下面這篇文章主要給大家介紹了關(guān)于Java中增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理和坑的相關(guān)資料,需要的朋友可以參考下
    2018-04-04
  • SpringMVC中處理靜態(tài)資源的過程詳解

    SpringMVC中處理靜態(tài)資源的過程詳解

    本文給大家介紹SpringMVC中處理靜態(tài)資源的過程,結(jié)合示例代碼給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11

最新評論