golang 中間業務層設計最佳實踐:基于接口和注冊機制的解耦方案
在多個業務模塊都依賴同一項復雜業務的情況下,如何設計中間業務層以避免代碼臃腫和難以維護,是一個重要的設計問題。本文將針對“創建a”業務,探討一種基于接口和注冊機制的解耦方案,有效解決原方案中 switch 語句導致的代碼堆積問題。
問題描述中,abcd 等多個業務模塊都需要調用 “創建a” 業務,并在調用前后進行各自的預處理和后處理。原方案使用 switch 語句進行區分,這在業務模塊增多時將變得難以維護。 因此,需要一種更優雅、可擴展的解決方案。
改進方案的核心在于利用 go 語言的接口特性和注冊機制。我們可以定義一個接口 handlepublica,包含 beforecreate、aftercreate 和 name 三個方法,分別代表創建a之前的處理,創建a之后的處理,以及業務模塊的標識。
各個業務模塊(如 a、b、c、d)都實現 handlepublica 接口,并在各自的 beforecreate 和 aftercreate 方法中實現具體的預處理和后處理邏輯。name 方法則返回該業務模塊的標識符。
立即學習“go語言免費學習筆記(深入)”;
創建a 業務本身則作為一個獨立的結構體 publica,其 do 方法包含核心業務邏輯。
通過這種設計,我們可以將各個業務模塊的處理邏輯解耦,避免了 switch 語句的累積。在運行時,我們可以通過一個 handlepublica 接口類型的切片 hooks 來注冊各個業務模塊,然后依次調用它們的 beforecreate 和 aftercreate 方法。
以下是一個具體的代碼示例:
type PublicAParam struct{} // 創建公共業務a需要的數據 type PublicA struct{} // 公共業務a type PublicARes struct{} // 公共業務a生成的數據 func (p PublicA)Do(name string) PublicARes { // 業務a自己的處理邏輯 return PublicARes{} } type HandlePublicA interface { BeforeCreate(PublicAParam)PublicA AfterCreate(PublicARes) Name() string } type A struct { // 其他業務A MyName string } func (a A)BeforeCreate(param PublicAParam) PublicA { return PublicA{} } func (a A)AfterCreate(PublicARes){} func (a A)Name() string { return a.MyName } func main(){ param := PublicAParam{} hooks := []HandlePublicA{A{MyName: "A"}} for i := range hooks{ p := hooks[i].BeforeCreate(param) after := p.Do(hooks[i].Name()) hooks[i].AfterCreate(after) } }
在這個示例中,publica 結構體代表 “創建a” 業務,handlepublica 接口定義了業務模塊需要實現的方法,a 結構體實現了 handlepublica 接口,并注冊到 hooks 切片中。 通過遍歷 hooks 切片,我們可以依次調用各個業務模塊的處理邏輯,實現了業務邏輯的解耦和擴展性。 publica.do 方法處理完后返回的結果,會被再次傳遞給各個業務模塊的aftercreate方法進行后續處理。