Golang设计模式之外观模式讲解和代码示例

 更新时间:2023年06月26日 08:27:25   作者:demo007x  
外观是一种结构型设计模式, 能为复杂系统、 程序库或框架提供一个简单 (但有限) 的接口,这篇文章就给大家详细介绍一下Golang的外观模式,文中有详细的代码示例,具有一定的参考价值,需要的朋友可以参考下

Go 外观模式讲解和代码示例

外观是一种结构型设计模式, 能为复杂系统、 程序库或框架提供一个简单 (但有限) 的接口。

尽管外观模式降低了程序的整体复杂度, 但它同时也有助于将不需要的依赖移动到同一个位置。

概念示例

人们很容易低估使用信用卡订购披萨时幕后工作的复杂程度。 在整个过程中会有不少的子系统发挥作用。 下面是其中的一部分:

  • 检查账户
  • 检查安全码
  • 借记/贷记余额
  • 账簿录入
  • 发送消息通知

在如此复杂的系统中, 可以说是一步错步步错, 很容易就会引发大的问题。 这就是为什么我们需要外观模式, 让客户端可以使用一个简单的接口来处理众多组件。 客户端只需要输入卡片详情、 安全码、 支付金额以及操作类型即可。

外观模式会与多种组件进一步地进行沟通, 而又不会向客户端暴露其内部的复杂性。

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: 复杂子系统的组成部分

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: 复杂子系统的组成部分

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: 复杂子系统的组成部分

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: 复杂子系统的组成部分

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: 复杂子系统的组成部分

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: 客户端代码

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())
	}
}

到此这篇关于Golang设计模式之外观模式讲解和代码示例的文章就介绍到这了,更多相关Golang 外观模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go Println和Printf的区别详解

    Go Println和Printf的区别详解

    这篇文章主要介绍了Go Println和Printf的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 如何go语言比较两个对象是否深度相同

    如何go语言比较两个对象是否深度相同

    这篇文章主要介绍了如何go语言比较两个对象是否深度相同,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • Go语言什么时候该使用指针

    Go语言什么时候该使用指针

    本文主要介绍了Go语言什么情况下应该使用指针,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Go标准库http server优雅启动深入理解

    Go标准库http server优雅启动深入理解

    这篇文章主要介绍了Go标准库http server优雅启动深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Golang Fasthttp选择使用slice而非map 存储请求数据原理探索

    Golang Fasthttp选择使用slice而非map 存储请求数据原理探索

    本文将从简单到复杂,逐步剖析为什么 Fasthttp 选择使用 slice 而非 map,并通过代码示例解释这一选择背后高性能的原因,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-02-02
  • 对Golang中的FORM相关字段理解

    对Golang中的FORM相关字段理解

    这篇文章主要介绍了对Golang中的FORM相关字段理解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Golang语言如何避免空指针引发的panic详解

    Golang语言如何避免空指针引发的panic详解

    简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增加了一些限制,这篇文章主要给大家介绍了关于Golang语言如何避免空指针引发panic的相关资料,需要的朋友可以参考下
    2022-01-01
  • Go语言中函数的参数传递与调用的基本方法

    Go语言中函数的参数传递与调用的基本方法

    这篇文章主要介绍了Go语言中函数的参数传递与调用的基本方法,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • golang 实现 pdf 转高清晰度 jpeg的处理方法

    golang 实现 pdf 转高清晰度 jpeg的处理方法

    这篇文章主要介绍了golang 实现 pdf 转高清晰度 jpeg,下面主要介绍Golang 代码使用方法及Golang PDF转JPEG的详细代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • 一文带你熟悉Go语言中的for循环

    一文带你熟悉Go语言中的for循环

    这篇文章主要和大家分享一下Go语言中for循环的定义与使用,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可以参考一下
    2022-11-11

最新评论