Golang 流水線設計模式實踐
流水線設計模式對於順序處理業務數據非常有用,可以以一致的方式直觀的定義對數據的處理流程。原文: Using a Pipeline Pattern in Golang[1]
到目前爲止,我已經將 Golang 整合到項目中有一段時間了,Golang 是一種非常強大的語言,我渴望在其生態系統中進一步磨練技能。
基於項目的特定需求,我需要實現流水線模式 (Pipeline Pattern),數據需要通過多個過濾器,以順序的方式進行處理。讓我解釋一下:
假設我們有一個很長的字符串。第一步是根據特定標準對其進行解析。接下來,需要對解析後的數據進行一些調整。隨後,將解析後的數據保存到數據庫中。正如你所見,有多個任務需要處理,而每個任務都是相互關聯的。
在軟件開發中,可以用流水線設計模式 (pipeline design pattern) 來管理這種場景,該模式是爲順序處理對象修改而設計的。想象有一條裝配流水線,每個工位都是一段 " 管道 (pipe)",當某個物體通過整個流水線後,就發生了變化。從本質上講,流水線負責將值通過一系列可調用的" 管道 (pipe)"(無論是中間件、過濾器還是處理器) 進行順序傳遞。在將該值傳遞給序列中的後續管道之前,每個管道段都有可能改變該值。該模式在諸如請求處理、數據處理或轉換等場景中特別有用,提供了一種乾淨、可維護和可測試的方法。
作爲解決方案,我準備了一個簡單的 Golang 包,可以在處理流程中使用流水線模式,它建立在責任鏈 (chain of responsibility, CoR) 設計模式之上,可以將其安裝到項目中並使用:
go get github.com/izniburak/pipeline-go
包安裝之後,可以做一個簡單演示。首先需要一些新的結構體,這些結構體具有從PipeInterface實現的Handle方法。因爲 pipeline 包需要多個流水線,所以我們用Handle方法來運行每個流水線:
package main
import (
"strings"
"github.com/izniburak/pipeline-go"
)
type UpperCasePipe struct{}
func (u *UpperCasePipe) Handle(value pipeline.PipeValue, next pipeline.PipeNext) pipeline.PipeValue {
// get value
text := value.(string)
capitalized := strings.ToUpper(text)
return next(capitalized)
}
type TrimSpacePipe struct{}
func (t *TrimSpacePipe) Handle(value pipeline.PipeValue, next pipeline.PipeNext) pipeline.PipeValue {
// get value
text := value.(string)
trimmed := strings.Trim(text, " ")
return next(trimmed)
}
然後可以開始使用流水線:
package main
import (
"fmt"
"strings"
"github.com/izniburak/pipeline-go"
)
type UpperCasePipe struct{}
func (u *UpperCasePipe) Handle(value pipeline.PipeValue, next pipeline.PipeNext) pipeline.PipeValue {
// get value
text := value.(string)
capitalized := strings.ToUpper(text)
return next(capitalized)
}
type TrimSpacePipe struct{}
func (t *TrimSpacePipe) Handle(value pipeline.PipeValue, next pipeline.PipeNext) pipeline.PipeValue {
// get value
text := value.(string)
trimmed := strings.Trim(text, " ")
return next(trimmed)
}
func main() {
text := " buki.dev "
pipes := []pipeline.PipeInterface{
new(UpperCasePipe),
new(TrimSpacePipe),
}
result := pipeline.Send(text).Through(pipes).ThenReturn()
fmt.Println(result) // BUKI.DEV
}
如你所見,我們使用了兩個不同的管道,分別是UpperCasePipe和TrimSpacePipe。輸入是 buki.dev ,兩邊都有空格,輸出是BUKI.DEV。
就是這樣。流水線非常有用,是吧?
可以在 GitHub 上查看 pipeline 包 [2]。
你好,我是俞凡,在 Motorola 做過研發,現在在 Mavenir 做技術工作,對通信、網絡、後端架構、雲原生、DevOps、CICD、區塊鏈、AI 等技術始終保持着濃厚的興趣,平時喜歡閱讀、思考,相信持續學習、終身成長,歡迎一起交流學習。爲了方便大家以後能第一時間看到文章,請朋友們關注公衆號 "DeepNoMind",並設個星標吧,如果能一鍵三連 (轉發、點贊、在看),則能給我帶來更多的支持和動力,激勵我持續寫下去,和大家共同成長進步!
參考資料
[1]
Using a Pipeline Pattern in Golang: https://tech.jotform.com/pipeline-go-pipeline-pattern-in-golang-5a51e5d811a
[2]
pipeline-go: https://github.com/izniburak/pipeline-go
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ka4o9Mfq2gyHJ_Z_gkR-vg