門面模式也叫外觀模式,英文為 Facade Design Pattern。門面模式為子系統提供一組統一的接口,定義一組高層接口讓子系統更易用。 門面模式的思想更常用在架構設計上,在編寫代碼層面大家很少提門面模式,但卻一直在默默的使用。
UML類圖位置:https://www.processon.com/diagraming/609b375407912943913a4c13
本文代碼連結為:https://github.com/shidawuhen/asap/blob/master/controller/design/15facade.go
1定義
1.1門面模式
門面模式:為子系統中的一組接口提供一個一緻的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
UML:
1.2分析
門面模式沒有太多好分析的,思想比較簡單。我方系統中包含多個子系統,完成一項任務需要多個子系統通力合作。
我們可以選擇将子系統所有接口暴露給Client,讓Client自行調用。但這會導緻一些問題,一是後期溝通成本會很高,加入完成一個功能需要調用多個接口,Client聯調時出問題率會飙升,系統提供者需要不斷答疑。二是如果有多個Client,相同代碼Client需要重複開發,而且後期代碼有變更,各方都會很煩費力。三是影響響應時間和性能,多個接口往返,白白增加了很多通信時間和請求量。
另一種方式是,對于指定功能,系統端做好封裝,隻提供一個接口。好處有很多,溝通成本低、Client不需要重複開發、功能更改影響範圍小、提高響應時間和性能。一般這些接口會有對應的OpenAPI,實作了功能對外開放的效果。
2.使用場景
對于使用場景,簡單的舉一個例子。
電商系統一般包含商品、庫存、營銷、商家、交易、支付、售後、履約、物流、倉儲等子系統。拿商品詳情頁來說,商詳頁接口一般會涉及商品、庫存、營銷、商家等系統。電商系統的用戶端有PC、Mobile、Android、IOS等,如果讓這些用戶端調用接口拼湊出商詳頁的資料,感覺用戶端的同學能拿着大砍刀和服務端同學談心。為了避免這種情況,一般商品組同學會提供商詳頁接口,該接口擷取商詳頁的所有資訊,傳回給用戶端。
當然,如果流量特别大,需要優化接口性能,可以根據具體情況将接口做拆分,用戶端需要請求多個接口,但即使這樣,相關的接口也是封裝好的。如果真實場景中遇到這種拆分的情況,那恭喜你,說明公司在發展,流量在增加,能夠推動大家更快的成長。
3.代碼實作
門面模式應該是大家用的最自然的一種設計模式了。簡單寫一下電商系統的門面模式代碼,以便和其它文章保持一緻。
package main
import "fmt"
type ProductSystem struct {
}
func (p *ProductSystem) GetProductInfo() {
fmt.Println("擷取到商品資訊")
}
type StockSystem struct {
}
func (s *StockSystem) GetStockInfo() {
fmt.Println("擷取到庫存資訊")
}
type PromotionSystem struct {
}
func (p *PromotionSystem) GetPromotionInfo() {
fmt.Println("擷取營銷資訊")
}
func ProductDetail() {
product := &ProductSystem{}
stock := &StockSystem{}
promotion := &PromotionSystem{}
product.GetProductInfo()
stock.GetStockInfo()
promotion.GetPromotionInfo()
fmt.Println("整理完成商品詳情頁所有資料")
}
func main() {
ProductDetail()
}
輸出:
➜ myproject go run main.go
擷取到商品資訊
擷取到庫存資訊
擷取營銷資訊
整理完成商品詳情頁所有資料
3.總結
門面模式是程式員最常用的一種設計模式了,在架構設計中往往自然而然的就會用到。很好的滿足了接口隔離原則和迪米特法則。
最後
大家如果喜歡我的文章,可以關注我的公衆号(程式員麻辣燙)
我的個人部落格為:https://shidawuhen.github.io/
往期文章回顧:
招聘
- 位元組跳動|内推大放送
- 位元組跳動|今日頭條廣州服務端研發工程師内推
- 位元組跳動|抖音電商急招上海前端開發工程
- 位元組跳動|抖音電商上海資深服務端開發工程師-交易
- 位元組跳動|抖音電商武漢服務端(進階)開發工程師
- 位元組跳動|飛書大客戶産品經理内推咯
- 位元組跳動|抖音電商服務端技術崗位虛位以待
- 位元組跳動招聘專題
設計模式
- Go設計模式(13)-裝飾器模式
- Go設計模式(12)-橋接模式
- Go設計模式(11)-代理模式
- Go設計模式(10)-原型模式
- Go設計模式(9)-建造者模式
- Go設計模式(8)-抽象工廠
- Go設計模式(7)-工廠模式
- Go設計模式(6)-單例模式
- Go設計模式(5)-類圖符号表示法
- Go設計模式(4)-代碼編寫優化
- Go設計模式(4)-代碼編寫
- Go設計模式(3)-設計原則
- Go設計模式(2)-面向對象分析與設計
- Go設計模式(1)-文法
語言
- 再也不怕擷取不到Gin請求資料了
- 一文搞懂pprof
- Go工具之generate
- Go單例實作方案
- Go通道實作原理
- Go定時器實作原理
- Beego架構使用
- Golang源碼BUG追查
- Gin架構簡潔版
- Gin源碼剖析
架構
- 分頁複選設計的坑
- 支付接入正常問題
- 限流實作2
- 秒殺系統
- 分布式系統與一緻性協定
- 微服務之服務架構和注冊中心
- 淺談微服務
- 限流實作1
- CDN請求過程詳解
- 常用緩存技巧
- 如何高效對接第三方支付
- 算法總結
存儲
- MySQL開發規範
- Redis實作分布式鎖
- 事務原子性、一緻性、持久性的實作原理
- InnoDB鎖與事務簡析
網絡
- HTTP2.0基礎教程
- HTTPS配置實戰
- HTTPS連接配接過程
- TCP性能優化
工具
- GoLand實用技巧
- 根據mysql表自動生成go struct
- Markdown編輯器推薦-typora
讀書筆記
- 《毛選》推薦
- 原則
- 資治通鑒
- 靈活革命
- 如何鍛煉自己的記憶力
- 簡單的邏輯學-讀後感
- 熱風-讀後感
- 論語-讀後感
- 孫子兵法-讀後感
思考
- 為動員一切力量争取勝利而鬥争
- 反對自由主義
- 實踐論
- 評價自己的标準
- 服務端團隊假期值班方案
- 項目流程管理
- 對項目管理的一些看法
- 對産品經理的一些思考
- 關于程式員職業發展的思考
- 關于代碼review的思考