Golang:设计模式之策略模式

小小的需求

获取一个csgo饰品的定价,需要从多个渠道(steam、buff、igxe......)等等。

需求很简单,下班前搞定吧。

开工

1、先定义一个传输对象:dto.go

Go 复制代码
package price

type GetPriceReq struct {
	GoodsId int64 `json:"goods_id"`
}

2、具体实现:interface.go

Go 复制代码
package price

import (
	"context"
	"strings"
)

// GoodsStrategyPrice 饰品定价策略
type GoodsStrategyPrice interface {
	// GetPrice 根据饰品ID获取系统自定义价格
	GetPrice(ctx context.Context, req *GetPriceReq) int64
}

// GoodsStrategy 用于选择和执行策略
type GoodsStrategy struct {
	strategy GoodsStrategyPrice
}

// SetStrategy 选择策略
func (s *GoodsStrategy) SetStrategy(strategy GoodsStrategyPrice) {
	s.strategy = strategy
}

// GetPrice 执行策略
func (s *GoodsStrategy) GetPrice(ctx context.Context, req *GetPriceReq) int64 {
	return s.strategy.GetPrice(ctx, req)
}

// GetPriceByGoods 根据策略获取价格
func GetPriceByGoods(ctx context.Context, req *GetPriceReq, strategy string) int64 {
	// 策略
	var strategyObj GoodsStrategyPrice

	// 去除空格、转小写
	strategy = strings.ToLower(strings.TrimSpace(strategy))

	switch strategy {
	case "steam":
		strategyObj = NewGoodsSteamPrice()
	case "buff":
		strategyObj = NewGoodsBuffPrice()
	case "igxe":
		strategyObj = NewGoodsIgxePrice()
	default: // 默认策略
		strategyObj = NewGoodsSteamPrice()
	}

	obj := &GoodsStrategy{}
	obj.SetStrategy(strategyObj)

	return obj.GetPrice(ctx, req)
}

// GoodsSteamPrice Steam定价
type GoodsSteamPrice struct{}

// NewGoodsSteamPrice 定价策略:Steam定价
func NewGoodsSteamPrice() *GoodsSteamPrice {
	return &GoodsSteamPrice{}
}

// GetPrice 根据饰品ID获取系统自定义价格:Steam定价
func (p *GoodsSteamPrice) GetPrice(ctx context.Context, req *GetPriceReq) int64 {
	return 100
}

// GoodsBuffPrice Buff定价
type GoodsBuffPrice struct{}

// NewGoodsBuffPrice 定价策略: Buff定价
func NewGoodsBuffPrice() *GoodsBuffPrice {
	return &GoodsBuffPrice{}
}

// GetPrice 根据饰品ID获取系统自定义价格:Buff定价
func (p *GoodsBuffPrice) GetPrice(ctx context.Context, req *GetPriceReq) int64 {
	return 200
}

// GoodsIgxePrice Igxe定价
type GoodsIgxePrice struct{}

// NewGoodsIgxePrice 定价策略: Igxe定价
func NewGoodsIgxePrice() *GoodsIgxePrice {
	return &GoodsIgxePrice{}
}

// GetPrice 根据饰品ID获取系统自定义价格:Igxe定价
func (p *GoodsIgxePrice) GetPrice(ctx context.Context, req *GetPriceReq) int64 {
	return 300
}
运行一下

是骡子是马,拉出来溜溜

Go 复制代码
package main

import (
	"fmt"
	"strategy/price"
)

func main() {

	strategy := "steam"

	priceData := price.GetPriceByGoods(nil, &price.GetPriceReq{GoodsId: 1}, strategy)

	fmt.Printf("策略:%s 定价:%d\n", strategy, priceData)
}

输出结果:

一气呵成,还真能运行起来,这你受得了嘛


解释一下

这段代码展示了策略模式(Strategy Pattern)的设计思想。策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。

以下是策略模式的关键组件在代码中的体现:

  1. **策略接口 (GoodsStrategyPrice):**定义了所有支持的策略或行为的公共接口。在这个例子中,接口声明了一个方法 GetPrice,用于根据饰品ID获取系统自定义价格。
  2. **具体策略类 (GoodsSteamPrice, GoodsBuffPrice, GoodsIgxePrice):**这些类实现了GoodsStrategyPrice接口,每种都代表了一种具体的定价策略。例如,GoodsSteamPrice 类的 GetPrice 方法返回100,模拟了Steam平台的定价规则。
  3. **上下文类 (GoodsStrategy):**此类用来封装使用哪种策略的上下文,并且提供了设置策略(SetStrategy)和执行策略(GetPrice)的方法。它持有一个GoodsStrategyPrice类型的策略对象,使得在运行时可以动态切换策略。
  4. **策略选择函数 (GetPriceByGoods):**这个函数根据传入的策略字符串参数,选择并实例化相应的策略对象,然后通过GoodsStrategy来执行选定的策略,获取价格。

通过这种方式,该设计允许程序在运行时选择不同的算法或策略来处理同一类型的问题,而无需知道具体策略是如何实现的,提高了代码的灵活性和可扩展性。如果未来需要添加新的定价策略,只需实现GoodsStrategyPrice接口并相应地修改策略选择逻辑即可。



我为人人,人人为我,美美与共,天下大同。

相关推荐
workflower7 小时前
情境感知系统
人工智能·机器学习·设计模式·自然语言处理·机器人
咖啡八杯9 小时前
设计模式中的原则
设计模式·接口隔离原则·里氏替换原则·开闭原则·合成复用原则·单一职责原则
安冬的码畜日常11 小时前
【工欲善其事】深入理解 Node.js 带并发上限的异步任务批量执行逻辑
javascript·设计模式·node.js·ai编程·异步编程·并发执行
AI大法师1 天前
一个机场如何被做成 IP 场景:宝可梦机场的设计方法总结
大数据·人工智能·设计模式·新媒体运营
晚安code1 天前
干掉成山的 if-else:工厂造、策略选,一文讲透两个模式的配合
后端·设计模式
workflower1 天前
从幻觉,到现实
人工智能·深度学习·机器学习·设计模式·机器人
电子科技圈1 天前
第二代无线平台历久弥新,赋能物联网创新迭代
人工智能·嵌入式硬件·mcu·物联网·设计模式·硬件架构·iot
choumin2 天前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
choumin2 天前
创建型模式——原型模式
c++·设计模式·原型模式·创建型模式
37.2℃9952 天前
Claude Design哪个公司技术好
python·设计模式