Golang設(shè)計(jì)模式之外觀模式講解和代碼示例
Go 外觀模式講解和代碼示例
外觀是一種結(jié)構(gòu)型設(shè)計(jì)模式, 能為復(fù)雜系統(tǒng)、 程序庫(kù)或框架提供一個(gè)簡(jiǎn)單 (但有限) 的接口。
盡管外觀模式降低了程序的整體復(fù)雜度, 但它同時(shí)也有助于將不需要的依賴(lài)移動(dòng)到同一個(gè)位置。
概念示例
人們很容易低估使用信用卡訂購(gòu)披薩時(shí)幕后工作的復(fù)雜程度。 在整個(gè)過(guò)程中會(huì)有不少的子系統(tǒng)發(fā)揮作用。 下面是其中的一部分:
- 檢查賬戶(hù)
- 檢查安全碼
- 借記/貸記余額
- 賬簿錄入
- 發(fā)送消息通知
在如此復(fù)雜的系統(tǒng)中, 可以說(shuō)是一步錯(cuò)步步錯(cuò), 很容易就會(huì)引發(fā)大的問(wèn)題。 這就是為什么我們需要外觀模式, 讓客戶(hù)端可以使用一個(gè)簡(jiǎn)單的接口來(lái)處理眾多組件。 客戶(hù)端只需要輸入卡片詳情、 安全碼、 支付金額以及操作類(lèi)型即可。
外觀模式會(huì)與多種組件進(jìn)一步地進(jìn)行溝通, 而又不會(huì)向客戶(hù)端暴露其內(nèi)部的復(fù)雜性。
walletFacade.go: 外觀
package main
import (
"fmt"
)
type WalletFacade struct {
account *Account
wallet *Wallet
securityCode *SecurityCode
notification *Notification
ledger *Ledger
}
func newWalletFacade(accountID string, code int) *WalletFacade {
fmt.Println("Starting create account")
var walletFacade = &WalletFacade{
account: newAccount(accountID),
securityCode: newSecurityCode(code),
wallet: newWallet(),
notification: &Notification{},
ledger: &Ledger{},
}
fmt.Println("Account created")
return walletFacade
}
func (w *WalletFacade) addMoneyToWallet(accountID string, securityCode int, amount int) error {
fmt.Println("Start add money to wallet")
err := w.account.checkAccount(accountID)
if err != nil {
return err
}
err = w.securityCode.checkCode(securityCode)
if err != nil {
return err
}
w.wallet.creditBalance(amount)
w.notification.sendWalletCreditNotification()
w.ledger.makeEntry(accountID, "credit", amount)
return nil
}
func (w *WalletFacade) deductMoneyFromWallet(accountID string, securityCode, amount int) error {
fmt.Println("Starting debit money from wallet")
err := w.account.checkAccount(accountID)
if err != nil {
return err
}
err = w.securityCode.checkCode(securityCode)
if err != nil {
return err
}
err = w.wallet.debitBalance(amount)
if err != nil {
return err
}
w.notification.sendWalletCreditNotification()
w.ledger.makeEntry(accountID, "debit", amount)
return nil
}account.go: 復(fù)雜子系統(tǒng)的組成部分
package main
import "fmt"
type Account struct {
name string
}
func newAccount(name string) *Account {
return &Account{
name: name,
}
}
func (a *Account) checkAccount(name string) error {
if a.name != name {
return fmt.Errorf("Account Name is incorrect")
}
fmt.Println("Account Verified")
return nil
}securityCode.go: 復(fù)雜子系統(tǒng)的組成部分
package main
import "fmt"
type SecurityCode struct {
code int
}
func newSecurityCode(code int) *SecurityCode {
return &SecurityCode{code: code}
}
func (s *SecurityCode) checkCode(incomingCode int) error {
if s.code != incomingCode {
return fmt.Errorf("Security Code is incorrect")
}
fmt.Println("SecurityCode Verified")
return nil
}wallet.go: 復(fù)雜子系統(tǒng)的組成部分
package main
import "fmt"
type Wallet struct {
balance int
}
func newWallet() *Wallet {
return &Wallet{balance: 0}
}
func (w *Wallet) creditBalance(amount int) {
w.balance += amount
fmt.Println("Wallet balance added successfully")
return
}
func (w *Wallet) debitBalance(amount int) error {
if w.balance < amount {
return fmt.Errorf("Balance is not sufficient")
}
w.balance -= amount
return nil
}ledger.go: 復(fù)雜子系統(tǒng)的組成部分
package main
import "fmt"
type Ledger struct{}
func (s *Ledger) makeEntry(accountID, txnType string, amount int) {
fmt.Printf("Make ledger entry for accountId %s with txnType %s for amount %d\n", accountID, txnType, amount)
return
}notification.go: 復(fù)雜子系統(tǒng)的組成部分
package main
import "fmt"
type Notification struct{}
func (n *Notification) sendWalletCreditNotification() {
fmt.Println("sending wallet credit notification")
}
func (n *Notification) sendWalletDebitNotification() {
fmt.Println("Sending wallet debit notification")
}main.go: 客戶(hù)端代碼
package main
import (
"fmt"
"log"
)
func main() {
fmt.Println()
walletFacade := newWalletFacade("abc", 1234)
fmt.Println()
err := walletFacade.addMoneyToWallet("abc", 1234, 10)
if err != nil {
log.Fatalf("error: %s \n", err.Error())
}
fmt.Println()
err = walletFacade.deductMoneyFromWallet("abc", 1234, 5)
if err != nil {
log.Fatalf("error: %s \n", err.Error())
}
}到此這篇關(guān)于Golang設(shè)計(jì)模式之外觀模式講解和代碼示例的文章就介紹到這了,更多相關(guān)Golang 外觀模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言Goroutines?泄漏場(chǎng)景與防治解決分析
這篇文章主要為大家介紹了Go語(yǔ)言Goroutines?泄漏場(chǎng)景與防治解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Golang報(bào)“import cycle not allowed”錯(cuò)誤的2種解決方法
這篇文章主要給大家介紹了關(guān)于Golang報(bào)"import cycle not allowed"錯(cuò)誤的2種解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以們下面隨著小編來(lái)一起看看吧2018-08-08
Golang Mutex實(shí)現(xiàn)互斥的具體方法
Mutex是Golang常見(jiàn)的并發(fā)原語(yǔ),在開(kāi)發(fā)過(guò)程中經(jīng)常使用到,本文主要介紹了Golang Mutex實(shí)現(xiàn)互斥的具體方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-04-04
聊聊golang中多個(gè)defer的執(zhí)行順序
這篇文章主要介紹了golang中多個(gè)defer的執(zhí)行順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05
golang語(yǔ)言如何將interface轉(zhuǎn)為int, string,slice,struct等類(lèi)型
這篇文章主要介紹了golang語(yǔ)言如何將interface轉(zhuǎn)為int, string,slice,struct等類(lèi)型,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

