一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 解析Java的設計模式編程之解釋器模式的運用

解析Java的設計模式編程之解釋器模式的運用

2020-04-01 14:04卡奴達摩 JAVA教程

這篇文章主要介紹了解析Java的設計模式編程之解釋器模式的運用,文中對解釋器模式的優缺點及適用場景作出了分析,需要的朋友可以參考下

定義:給定一種語言,定義他的文法的一種表示,并定義一個解釋器,該解釋器使用該表示來解釋語言中句子。
類型:行為類模式
類圖:

解析Java的設計模式編程之解釋器模式的運用

解釋器模式是一個比較少用的模式,本人之前也沒有用過這個模式。下面我們就來一起看一下解釋器模式。
 
解釋器模式的結構
抽象解釋器:聲明一個所有具體表達式都要實現的抽象接口(或者抽象類),接口中主要是一個interpret()方法,稱為解釋操作。具體解釋任務由它的各個實現類來完成,具體的解釋器分別由終結符解釋器TerminalExpression和非終結符解釋器NonterminalExpression完成。
終結符表達式:實現與文法中的元素相關聯的解釋操作,通常一個解釋器模式中只有一個終結符表達式,但有多個實例,對應不同的終結符。終結符一半是文法中的運算單元,比如有一個簡單的公式R=R1+R2,在里面R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。                               
非終結符表達式:文法中的每條規則對應于一個非終結符表達式,非終結符表達式一般是文法中的運算符或者其他關鍵字,比如公式R=R1+R2中,+就是非終結符,解析+的解釋器就是一個非終結符表達式。非終結符表達式根據邏輯的復雜程度而增加,原則上每個文法規則都對應一個非終結符表達式。
環境角色:這個角色的任務一般是用來存放文法中各個終結符所對應的具體值,比如R=R1+R2,我們給R1賦值100,給R2賦值200。這些信息需要存放到環境角色中,很多情況下我們使用Map來充當環境角色就足夠了。

例子
來舉一個加減乘除的例子吧,實現思路來自于《java與模式》中的例子。每個角色的功能按照上面提到的規范來實現。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//上下文(環境)角色,使用HashMap來存儲變量對應的數值
 
class Context
 
{
 
    private Map valueMap = new HashMap();
 
    public void addValue(Variable x , int y)
 
    {
 
       Integer yi = new Integer(y);
 
       valueMap.put(x , yi);
 
    }
 
    public int LookupValue(Variable x)
 
    {
 
       int i = ((Integer)valueMap.get(x)).intValue();
 
       return i ;
 
    }
 
}
 
//抽象表達式角色,也可以用接口來實現
 
abstract class Expression
 
{
 
    public abstract int interpret(Context con);
 
}
 
 
//終結符表達式角色
 
class Constant extends Expression
 
{
 
    private int i ;
 
    public Constant(int i)
 
    {
 
       this.i = i;
 
    }
 
    public int interpret(Context con)
 
    {
 
       return i ;
 
    }
 
}
 
 
class Variable extends Expression
 
{
 
    public int interpret(Context con)
 
    {
 
       //this為調用interpret方法的Variable對象
 
       return con.LookupValue(this);
 
    }
 
}
 
 
//非終結符表達式角色
 
class Add extends Expression
 
{
 
    private Expression left ,right ;
 
    public Add(Expression left , Expression right)
 
    {
 
       this.left = left ;
 
       this.right= right ;
 
    }
 
    public int interpret(Context con)
 
    {
 
       return left.interpret(con) + right.interpret(con);
 
    }
 
}
 
 
class Subtract extends Expression
 
{
 
    private Expression left , right ;
 
    public Subtract(Expression left , Expression right)
 
    {
 
       this.left = left ;
 
       this.right= right ;
 
    }
 
    public int interpret(Context con)
 
    {
 
       return left.interpret(con) - right.interpret(con);
 
    }
 
}
 
class Multiply extends Expression
 
{
 
    private Expression left , right ;
 
    public Multiply(Expression left , Expression right)
 
    {
 
       this.left = left ;
 
       this.right= right ;
 
    }
 
    public int interpret(Context con)
 
    {
 
       return left.interpret(con) * right.interpret(con);
 
    }
 
}
 
class Division extends Expression
 
{
 
    private Expression left , right ;
 
    public Division(Expression left , Expression right)
 
    {
 
       this.left = left ;
 
       this.right= right ;
 
    }
 
    public int interpret(Context con)
 
    {
 
       try{
 
              return left.interpret(con) / right.interpret(con);
 
       }catch(ArithmeticException ae)
 
       {
 
           System.out.println("被除數為0!");
 
           return -11111;
 
       }
 
    }
 
}
 
//測試程序,計算 (a*b)/(a-b+2)
 
public class Test
 
{
 
    private static Expression ex ;
 
    private static Context con ;
 
    public static void main(String[] args)
 
    {
 
       con = new Context();
 
       //設置變量、常量
 
       Variable a = new Variable();
 
       Variable b = new Variable();
 
       Constant c = new Constant(2);
 
//為變量賦值
 
       con.addValue(a , 5);
 
       con.addValue(b , 7);
 
//運算,對句子的結構由我們自己來分析,構造
 
       ex = new Division(new Multiply(a , b), new Add(new Subtract(a , b) , c));
 
       System.out.println("運算結果為:"+ex.interpret(con));
 
    }
 
}

解釋器模式的優缺點
        解釋器是一個簡單的語法分析工具,它最顯著的優點就是擴展性,修改語法規則只需要修改相應的非終結符就可以了,若擴展語法,只需要增加非終結符類就可以了。
        但是,解釋器模式會引起類的膨脹,每個語法都需要產生一個非終結符表達式,語法規則比較復雜時,就可能產生大量的類文件,為維護帶來非常多的麻煩。同時,由于采用遞歸調用方法,每個非終結符表達式只關心與自己相關的表達式,每個表達式需要知道最終的結果,必須通過遞歸方式,無論是面向對象的語言還是面向過程的語言,遞歸都是一個不推薦的方式。由于使用了大量的循環和遞歸,效率是一個不容忽視的問題。特別是用于解釋一個解析復雜、冗長的語法時,效率是難以忍受的。
 
解釋器模式的適用場景
        在以下情況下可以使用解釋器模式:
有一個簡單的語法規則,比如一個sql語句,如果我們需要根據sql語句進行rm轉換,就可以使用解釋器模式來對語句進行解釋。
一些重復發生的問題,比如加減乘除四則運算,但是公式每次都不同,有時是a+b-c*d,有時是a*b+c-d,等等等等個,公式千變萬化,但是都是由加減乘除四個非終結符來連接的,這時我們就可以使用解釋器模式。


注意事項
       解釋器模式真的是一個比較少用的模式,因為對它的維護實在是太麻煩了,想象一下,一坨一坨的非終結符解釋器,假如不是事先對文法的規則了如指掌,或者是文法特別簡單,則很難讀懂它的邏輯。解釋器模式在實際的系統開發中使用的很少,因為他會引起效率、性能以及維護等問題。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲www视频 | 国产午夜免费 | 91美女在线观看 | 99精品免费观看 | chinese圣水黄金调教 | 亚洲麻豆精品 | 性插图动态图无遮挡 | 色就色综合 | 四虎精品视频在线永久免费观看 | 婷婷99av综合| 亚洲国产自拍在线 | 91制片厂制作果冻传媒破解 | 亚洲视频在线观看地址 | 暖暖免费高清完整版观看日本 | nxgx国产 | 办公室里被迫高h | 香蕉精品高清在线观看视频 | 精品卡1卡2卡三卡免费视频 | 久久久亚洲国产精品主播 | 亚洲色图图 | 精品一区二区三区在线成人 | 青青草国产免费国产是公开 | 亚洲一二区视频 | 国产日韩一区二区三区 | 国产精品久久久久无毒 | www四虎影院 | 女人麻豆国产香蕉久久精品 | 国产资源视频在线观看 | 黄www片 | 男人疯狂进女人下部视频动漫 | 成人精品视频 成人影院 | 99re在线视频观看 | 国产在线99| 国产重口老太伦 | 日本护士撒尿xxxx欧美 | 国产a一级毛片午夜剧院 | 亚洲七七久久综合桃花 | 国产欧美精品一区二区三区四区 | 国产在线麻豆波多野结衣 | 500福利第一巨人导航 | 羞羞视频污 |