設計模式學習-使用go實現外觀模式


外觀模式

定義

外觀模式也叫門面模式

外觀模式(Facade),為子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

適用范圍

1、解決易用性問題

門面模式可以用來封裝系統的底層實現,隱藏系統的復雜性,提供一組更加簡單易用、更高層的接口。

2、解決性能問題

我們通過將多個接口調用替換為一個門面接口調用,減少網絡通信成本,提高App客戶端的響應速度。

假設有一個系統A,提供了a、b、c、d四個接口。系統B完成某個業務功能,需要調用A系統的a、b、d接口。利用門面模式,我們提供一個包裹a、b、d接口調用的門面接口x,給系統B直接使用。

3、解決分布式事務問題

這個直接來個栗子吧

比如我們現在設計微服務,一個用戶服務,一個金幣服務。每個服務都提供對外的增刪查改等操作。現在我們有一個需求,新用戶登陸之后送用戶金幣。簡單地調用,肯定是創建一個用戶信息,之后調用金幣服務給這個用戶加金幣。當然實際地開發中我們肯定要考慮分布式事務,保障這兩個操作肯定能一起成功或失敗,不能出現一個成功一個失敗的場景。當然我們常規的做法肯定是引入分布式框架,或者補償的機制來處理。

其實借助於門面模式的思想也是可以處理,我們可以設計一個包裹這兩個操作的新接口,讓新接口在一個事務中執行兩個SQL操作。

代碼實現

假設有一個系統A,提供了a、b、c、d四個接口。系統B完成某個業務功能,需要調用A系統的a、b、d接口。利用門面模式,我們提供一個包裹a、b、d接口調用的門面接口x,給系統B直接使用。

type User struct {
}

func (u *User) GetUser(userId int) {
	fmt.Println("獲取用戶的信息")
}

type GoldCoin struct {
}

func (g *GoldCoin) GetUserGoldCoin(userId int) {
	fmt.Println("獲取用戶金幣的信息")
}

type Order struct {
}

func (o *Order) GetUserOrder(userId int) {
	fmt.Println("獲取用戶訂單信息")
}

func GetUserInfo(userId int) {
	user := User{}
	user.GetUser(userId)

	goldCoin := GoldCoin{}
	goldCoin.GetUserGoldCoin(userId)

	order := Order{}
	order.GetUserOrder(userId)
}

放一張結構圖

facade

優點

  • 對客戶屏蔽子系統組件,減少了客戶處理的對象數目並使得子系統使用起來更加容易。

  • 實現了子系統與客戶之間的松耦合關系,這使得子系統的組件變化不會影響到調用它的客戶類,只需要調整外觀類即可。

  • 降低了大型軟件系統中的編譯依賴性,並簡化了系統在不同平台之間的移植過程,因為編譯一個子系統一般不需要編譯所有其他的子系統。一個子系統的修改對其他子系統沒有任何影響,而且子系統內部變化也不會影響到外觀對象。

  • 只是提供了一個訪問子系統的統一入口,並不影響用戶直接使用子系統類。

缺點

  • 不能很好地限制客戶使用子系統類,如果對客戶訪問子系統類做太多的限制則減少了可變性和靈活性。

  • 在不引入抽象外觀類的情況下,增加新的子系統可能需要修改外觀類或客戶端的源代碼,違背了“開閉原則”。

關於接口粒度的思考

接口粒度設計得太大,太小都不好。太大會導致接口不可復用,太小會導致接口不易用。在實際的開發中,接口的可復用性和易用性需要“微妙”的權衡。

針對這個問題,王爭大佬給出了一個原則,可以作為參考,盡量保持接口的可復用性,但針對特殊情況,允許提供冗余的門面接口,來提供更易用的接口

參考

【文中代碼】https://github.com/boilingfrog/design-pattern-learning/tree/master/外觀模式
【大話設計模式】https://book.douban.com/subject/2334288/
【極客時間】https://time.geekbang.org/column/intro/100039001
【外觀模式】https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/facade.html
【原文地址】https://boilingfrog.github.io/2021/11/15/使用go實現外觀模式/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM