Golang 策略模式

Jackey Golang 3,436 次浏览 , 6条评论

什么是策略模式?

不同的算法按照统一的标准封装,客户端根据不同的场景,决策使用何种算法。

优势

  • 典型的高内聚:算法和算法之间完全独立、互不干扰
  • 典型的松耦合:客户端依赖的是接口的抽象方法
  • 沉淀:每一个封装好的算法都是这个技术团队的财富,且未来可以被轻易的修改、复用

使用场景

当代码的下一步面临选择的时候都可以使用「策略模式」,我们把不同选择的算法按照统一的标准封装,得到一类算法集的过程,就是实现「策略模式」的过程。

实现代码

package main

import (
  "fmt"
  "runtime"
)

//------------------------------------------------------------
//我的代码没有`else`系列
//策略模式
//@auhtor TIGERB<https://github.com/TIGERB>
//------------------------------------------------------------

const (
  // ConstWechatPay 微信支付
  ConstWechatPay = "wechat_pay"
  // ConstAliPayWap 支付宝支付 网页版
  ConstAliPayWap = "AliPayWapwap"
  // ConstBankPay 银行卡支付
  ConstBankPay = "quickbank"
)

// Context 上下文
type Context struct {
  // 用户选择的支付方式
  PayType string `json:"pay_type"`
}

// PaymentInterface 支付方式接口
type PaymentInterface interface {
  Pay(ctx *Context) error    // 支付
  Refund(ctx *Context) error // 退款
}

// WechatPay 微信支付
type WechatPay struct {
}

// Pay 当前支付方式的支付逻辑
func (p *WechatPay) Pay(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用微信支付...")
  return
}

// Refund 当前支付方式的支付逻辑
func (p *WechatPay) Refund(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用微信退款...")
  return
}

// AliPayWap 支付宝网页版
type AliPayWap struct {
}

// Pay 当前支付方式的支付逻辑
func (p *AliPayWap) Pay(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用支付宝网页版支付...")
  return
}

// Refund 当前支付方式的支付逻辑
func (p *AliPayWap) Refund(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用支付宝网页版退款...")
  return
}

// BankPay 银行卡支付
type BankPay struct {
}

// Pay 当前支付方式的支付逻辑
func (p *BankPay) Pay(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用银行卡支付...")
  return
}

// Refund 当前支付方式的支付逻辑
func (p *BankPay) Refund(ctx *Context) (err error) {
  // 当前策略的业务逻辑写这
  fmt.Println(runFuncName(), "使用银行卡退款...")
  return
}

// 获取正在运行的函数名
func runFuncName() string {
  pc := make([]uintptr, 1)
  runtime.Callers(2, pc)
  f := runtime.FuncForPC(pc[0])
  return f.Name()
}

func main() {
  // 相对于被调用的支付策略 这里就是支付策略的客户端

  // 业务上下文
  ctx := &Context{
    PayType: "wechat_pay",
  }

  // 获取支付方式
  var instance PaymentInterface
  switch ctx.PayType {
  case ConstWechatPay:
    instance = &WechatPay{}
  case ConstAliPayWap:
    instance = &AliPayWap{}
  case ConstBankPay:
    instance = &BankPay{}
  default:
    panic("无效的支付方式")
  }

  // 支付
  instance.Pay(ctx)
}

运行结果:

main.(*WechatPay).Pay 使用微信支付...

参考文章:https://studygolang.com/articles/29048

6条评论

  1. K先生个人博客 2020年6月6日 下午11:46 回复

    写的不错,博主交换友链吗?http://www.gold404.cn/虽然日流量只有几十,但一直在进步,还有那个啥,我也是一个想转go的php程序员。。。。

    • gopher 2020年6月8日 上午9:28 回复

      可以做哈,做好后通知我下

      • K先生个人博客 2020年6月8日 下午9:39 回复

        友链已做,你有时间记得也做下我的哈。
        K先生个人博客http://www.gold404.cn

        • gopher 2020年6月9日 上午9:23 回复

          已做好

  2. K先生个人博客 2020年6月8日 下午9:40 回复

    想问下博主现在的工作是PHP还是Go啊

    • gopher 2020年6月9日 上午9:24 回复

      PHP和Go都在写

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Go