自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go設(shè)計(jì)模式--解釋器模式

開發(fā) 開發(fā)工具
在程序中使用解釋器模式的目標(biāo)是: 定義特定于領(lǐng)域的語言及其語法,使用 AST(抽象語法樹)表示語言中的表達(dá)式或句子,好讓程序能夠根據(jù)一組規(guī)則或操作解釋或評估表達(dá)式。

大家好,這里是每周都在陪你一起進(jìn)步的網(wǎng)管~!今天繼續(xù)學(xué)習(xí)設(shè)計(jì)模式—解釋器模式

解釋器模式是一種行為設(shè)計(jì)模式,可以用來在程序里創(chuàng)建針對一個特點(diǎn)領(lǐng)域語言的解釋器,用于處理解釋領(lǐng)域語言中的語句。換句話說,該模式定義了領(lǐng)域語言的抽象語法樹以及用示來解釋語法樹的解釋器。

模式使用場景

解釋器模式,用于解決需要解釋語言中的句子或表達(dá)式的問題。以下是一些可以在 程序中使用解釋器模式的真實(shí)場景:

  • 處理配置文件

許多應(yīng)用程序使用配置文件來指定應(yīng)用程序的行為方式。這些配置文件可以用 YAML 或 JSON 等 DSL 編寫。解釋器可用于解析這些配置文件并以應(yīng)用編程語言對象的形式向應(yīng)用程序提供配置信息。

  • 模板引擎
  • 模板引擎處理模板和一組變量以產(chǎn)生輸出。模板是DSL的一個例子,可以使用Interpreter來解析和處理模板。
  • 數(shù)學(xué)表達(dá)式計(jì)算器
  • 數(shù)學(xué)表達(dá)式是我們?nèi)粘6寄芙佑|到的,使用了一種特定領(lǐng)域語言語法書寫語句或者叫表達(dá)式的實(shí)例
  • 這些表達(dá)式在程序里可以使用解釋器模式進(jìn)行解析和解釋。例如,計(jì)算器應(yīng)用程序可以使用解釋器來解析和評估用戶輸入的數(shù)學(xué)表達(dá)式。
  • 自然語言處理
  • 在更高級的情況下,解釋器模式可用于解析和解釋自然語言,不過這通常會涉及想機(jī)器學(xué)習(xí)這樣的更復(fù)雜的技術(shù)。

雖然解釋器模式可以用來解決這些問題,但它并不總是最好的解決方案。對于復(fù)雜的語言,使用特定的解析庫或工具或其他設(shè)計(jì)模式可能更有效。

下面我們先來學(xué)習(xí)一下解釋器模式的結(jié)構(gòu)組成,然后再嘗試用代碼自己實(shí)現(xiàn)一個解釋器。

圖片


模式構(gòu)成

解釋器模式中的關(guān)鍵組件有:

  • 表達(dá)式接口:表示抽象語法樹的元素并定義解釋表達(dá)式的方法。
  • 具體表達(dá)式:實(shí)現(xiàn)表達(dá)式接口的結(jié)構(gòu),表示語言語法的各種規(guī)則或元素。
  • 上下文對象:用于保存解釋過程中所需的任何必要信息或狀態(tài)。
  • Parser 或 Builder:負(fù)責(zé)根據(jù)輸入表達(dá)式構(gòu)建抽象語法樹的組件。

下面是解釋器模式構(gòu)成的UML類圖:

看完解釋器模式的結(jié)構(gòu)組成后,我們接下來嘗試應(yīng)用解釋器模式,用代碼實(shí)現(xiàn)一個加法運(yùn)算的解釋器。

實(shí)現(xiàn)解釋器模式

看了上面解釋器的結(jié)構(gòu)組成后我們結(jié)下來通過代碼一步步實(shí)現(xiàn)其核心組件來演示怎么用代碼實(shí)現(xiàn)解釋器模式。

以下是如何在 Go 中實(shí)現(xiàn)解釋器模式的步驟。

  1. 定義表示抽象語法樹中元素的表達(dá)式接口。
  2. 創(chuàng)建實(shí)現(xiàn) Expression 接口的具體表達(dá)式結(jié)構(gòu),例如 TerminalExpression 和 NonTerminalExpression。
  3. 定義一個上下文結(jié)構(gòu)來保存解釋過程中可能需要的任何必要數(shù)據(jù)或狀態(tài)(這一步可選)。
  4. 創(chuàng)建解析器或構(gòu)建器以根據(jù)輸入表達(dá)式構(gòu)造抽象語法樹。 使用創(chuàng)建的抽象語法樹和上下文解釋表達(dá)式。

這里簡單實(shí)現(xiàn)一個加減的運(yùn)算器,我們對每種運(yùn)算定義對應(yīng)的Expression對象,在方法里實(shí)現(xiàn)具體的運(yùn)算規(guī)則,避免所有的運(yùn)算操作放到一個函數(shù)中,這體現(xiàn)了解釋器模式的核心思想,將語法解析的工作拆分到各個小類中,以此來避免大而全的解析類。

我們先按照上面的步驟一,定義數(shù)學(xué)運(yùn)算這一領(lǐng)域語言里表示抽象語法樹中元素的表達(dá)式接口:

type Expression interface {
 Interpret() int
}

接下來創(chuàng)建Expression接口的具體實(shí)現(xiàn)類,在我們的加減法運(yùn)算中需要實(shí)現(xiàn)操作數(shù)、加法、減法對應(yīng)的實(shí)現(xiàn)類。

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
type NumberExpression struct {
 val int
}
// 解釋--返回其整數(shù)值
func (n *NumberExpression) Interpret() int {
 return n.val
}

// 加法運(yùn)算
type AdditionExpression struct {
 left, right Expression
}
// 解釋--進(jìn)行加法操作
func (n *AdditionExpression) Interpret() int {
 return n.left.Interpret() + n.right.Interpret()
}
// 減法運(yùn)算
type SubtractionExpression struct {
 left, right Expression
}
// 解釋--進(jìn)行減法運(yùn)算
func (n *SubtractionExpression) Interpret() int {
 return n.left.Interpret() - n.right.Interpret()
}

最后我們創(chuàng)建一個表達(dá)式解析器,它會根據(jù)輸入表達(dá)式構(gòu)造抽象語法樹,使用創(chuàng)建的抽象語法樹和上下文解釋表達(dá)式。

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
type Parser struct {
 exp   []string
 index int
 prev  Expression
}

func (p *Parser) Parse(exp string) {
 p.exp = strings.Split(exp, " ")

 for {
  if p.index >= len(p.exp) {
   return
  }
  switch p.exp[p.index] {
  case "+":
   p.prev = p.newAdditionExpression()
  case "-":
   p.prev = p.newSubtractionExpression()
  default:
   p.prev = p.newNumberExpression()
  }
 }
}

func (p *Parser) newAdditionExpression() Expression {
 p.index++
 return &AdditionExpression{
  left:  p.prev,
  right: p.newNumberExpression(),
 }
}

func (p *Parser) newSubtractionExpression() Expression {
 p.index++
 return &SubtractionExpression{
  left:  p.prev,
  right: p.newNumberExpression(),
 }
}

func (p *Parser) newNumberExpression() Expression {
 v, _ := strconv.Atoi(p.exp[p.index])
 p.index++
 return &NumberExpression{
  val: v,
 }
}
// 返回Expression實(shí)例
// 調(diào)用Interpret方法會從右向左遞歸計(jì)算出公式結(jié)果
func (p *Parser) Result() Expression {
 return p.prev
}

最后,我們用使用 Parse 把客戶端傳遞過來的加減法表達(dá)式解析成抽象語法樹,然后運(yùn)行解釋器計(jì)算加減法表達(dá)式的結(jié)果。

"本文使用的完整可運(yùn)行源碼
去公眾號「網(wǎng)管叨bi叨」發(fā)送【設(shè)計(jì)模式】即可領(lǐng)取"
func main() {
 p := &Parser{}
 p.Parse("1 + 3 + 3 + 3 - 3")
 res := p.Result().Interpret()
 expect := 7
 if res != expect {
  log.Fatalf("error: expect %d got %d", expect, res)
 }

 fmt.Printf("expect: %d, got: %d", expect, res)
}

圖片


總結(jié)

在程序中使用解釋器模式的目標(biāo)是: 定義特定于領(lǐng)域的語言及其語法,使用 AST(抽象語法樹)表示語言中的表達(dá)式或句子,好讓程序能夠根據(jù)一組規(guī)則或操作解釋或評估表達(dá)式

最后我們再來列舉一下解釋器模式的優(yōu)缺點(diǎn)。 使用解釋器模式的優(yōu)點(diǎn)是:

  • 關(guān)注點(diǎn)分離:該模式將解釋邏輯與數(shù)據(jù)表示分開。
  • 可擴(kuò)展性:可以通過添加新的表達(dá)式結(jié)構(gòu)輕松地?cái)U(kuò)展模式。
  • 可重用性:解釋器模式可以在需要解析或解釋特定領(lǐng)域語言的不同項(xiàng)目或上下文中重用。

使用解釋器模式的缺點(diǎn)是:

  • 復(fù)雜性:隨著語法規(guī)則數(shù)量的增加,模式會變得復(fù)雜。
  • 性能:對于大型表達(dá)式,抽象語法樹的遞歸遍歷可能很慢。


責(zé)任編輯:武曉燕 來源: 網(wǎng)管叨bi叨
相關(guān)推薦

2020-11-09 08:20:33

解釋器模式

2010-04-21 08:38:18

解釋器模式PHP設(shè)計(jì)模式

2023-05-04 08:47:31

命令模式抽象接口

2023-04-10 09:20:13

設(shè)計(jì)模式訪客模式

2023-03-03 08:12:07

設(shè)計(jì)模式語言

2021-07-07 10:31:19

對象池模式解釋器模式設(shè)計(jì)模式

2023-05-26 08:41:23

模式Go設(shè)計(jì)模式

2024-06-05 09:41:41

2013-01-11 09:40:56

設(shè)計(jì)模式.NET

2023-09-04 13:14:00

裝飾器設(shè)計(jì)模式

2023-03-21 07:57:37

Go語言設(shè)計(jì)模式

2023-12-13 13:28:16

裝飾器模式Python設(shè)計(jì)模式

2021-06-22 15:27:13

設(shè)計(jì)模式迭代器模式Java

2024-12-24 11:01:58

2023-03-27 00:20:48

2022-01-19 08:21:12

設(shè)計(jì)裝飾器模式

2010-04-29 08:53:11

PHP迭代器模式

2024-02-23 12:11:53

裝飾器模式對象

2021-02-01 10:01:58

設(shè)計(jì)模式 Java單例模式

2023-03-06 08:46:12

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號