Golang学习笔记_39——策略模式

Golang学习笔记_36——装饰器模式
Golang学习笔记_37——外观模式
Golang学习笔记_38——享元模式



一、核心概念

1. 定义

策略模式是一种行为型设计模式,通过定义一系列可互换的算法,并将其封装为独立类,使得算法可以独立于客户端而变化。核心思想是将算法与使用场景解耦,支持运行时动态切换策略。

2. 解决的问题
  • 算法频繁切换:需要根据不同条件选择不同算法(如支付方式、折扣策略)
  • 消除条件判断:避免大量if-elseswitch-case语句
  • 算法复用性:同一算法被多个客户端调用(如排序、压缩算法)
3. 核心角色
角色作用
Strategy策略接口,定义算法的公共方法(如Execute()
ConcreteStrategy具体策略实现类(如支付宝支付、微信支付)
Context上下文类,持有策略引用并执行算法
4. 类图

策略模式类图

@startuml
class Context {
    - strategy: Strategy
    + SetStrategy()
    + ExecuteStrategy()
}

interface Strategy {
    + Execute()
}

class ConcreteStrategyA {
    + Execute()
}

class ConcreteStrategyB {
    + Execute()
}

Context o--> Strategy
Strategy <|.. ConcreteStrategyA
Strategy <|.. ConcreteStrategyB
@enduml

二、特点分析

优点

  1. 开闭原则:新增策略无需修改现有代码
  2. 代码清晰:消除复杂条件判断,提升可维护性
  3. 灵活扩展:运行时动态切换策略(如游戏AI行为切换)

缺点

  1. 类数量膨胀:每个策略需单独定义类
  2. 客户端耦合:客户端需了解所有策略的存在

三、适用场景

1. 支付系统
  • 策略接口PaymentStrategy
  • 具体策略:信用卡、支付宝、微信支付
  • 动态切换:用户下单时选择支付方式
// 策略接口
type PaymentStrategy interface {
	Pay(amount float64) string
}

// 具体策略:支付宝
type AlipayStrategy struct{}
func (a *AlipayStrategy) Pay(amount float64) string {
	return fmt.Sprintf("支付宝支付%.2f元", amount)
}
2. 数据压缩
  • 策略接口CompressionStrategy
  • 具体策略:ZIP、RAR、7z算法
  • 按需选择:根据文件类型自动选择压缩算法
// 策略接口
type CompressionStrategy interface {
	Compress(file string) []byte
}

// 具体策略:ZIP压缩
type ZipStrategy struct{}
func (z *ZipStrategy) Compress(file string) []byte {
	return []byte("ZIP压缩后的数据")
}
3. 游戏AI
  • 策略接口AIBehavior
  • 具体策略:进攻、防御、逃跑模式
  • 动态调整:根据玩家血量切换NPC行为
// 策略接口
type AIBehavior interface {
	Act() string
}

// 具体策略:防御模式
type DefenseBehavior struct{}
func (d *DefenseBehavior) Act() string {
	return "进入防御状态"
}
4. 折扣计算
  • 策略接口DiscountStrategy
  • 具体策略:普通用户9折、VIP用户8折
  • 组合策略:叠加满减和折扣(见高级应用)

四、代码示例(Go语言)

场景:电商会员折扣系统

在这里插入图片描述

package strategydemo

// 策略接口
type DiscountStrategy interface {
	Calculate(price float64) float64
}

// 具体策略:普通会员
type NormalDiscount struct{}
func (n *NormalDiscount) Calculate(price float64) float64 {
	return price * 0.9 // 9折
}

// 具体策略:VIP会员
type VIPDiscount struct{}
func (v *VIPDiscount) Calculate(price float64) float64 {
	return price * 0.8 // 8折
}

// 上下文类
type Order struct {
	strategy DiscountStrategy
}

func (o *Order) SetStrategy(s DiscountStrategy) {
	o.strategy = s
}

func (o *Order) Checkout(price float64) float64 {
	return o.strategy.Calculate(price)
}

// 客户端使用
func TestStrategy() {
	order := &Order{}
	
	// 普通用户
	order.SetStrategy(&NormalDiscount{})
	fmt.Printf("普通用户价格: %.2f\n", order.Checkout(100)) // 90.00
	
	// 切换为VIP策略
	order.SetStrategy(&VIPDiscount{})
	fmt.Printf("VIP用户价格: %.2f\n", order.Checkout(100)) // 80.00
}
执行结果
=== RUN   Test_TestStrategy
普通用户价格: 90.00
VIP用户价格: 80.00
--- PASS: Test_TestStrategy (0.00s)
PASS

五、高级应用

1. 策略工厂模式
// 策略工厂(带注册机制)
type StrategyFactory struct {
	strategies map[string]DiscountStrategy
}

func NewStrategyFactory() *StrategyFactory {
	return &StrategyFactory{
		strategies: map[string]DiscountStrategy{
			"normal": &NormalDiscount{},
			"vip":    &VIPDiscount{},
		},
	}
}

// 动态获取策略
func (f *StrategyFactory) GetStrategy(key string) DiscountStrategy {
	return f.strategies[key]
}

// 使用示例
factory := NewStrategyFactory()
order.SetStrategy(factory.GetStrategy("vip"))
2. 组合策略
// 组合折扣(满300减50 + VIP折扣)
type CompositeDiscount struct {
	strategies []DiscountStrategy
}

func (c *CompositeDiscount) Calculate(price float64) float64 {
	for _, s := range c.strategies {
		price = s.Calculate(price)
	}
	return price
}

// 使用示例
composite := &CompositeDiscount{
	strategies: []DiscountStrategy{
		&FullReductionStrategy{Threshold: 300, Reduce: 50},
		&VIPDiscount{},
	},
}
fmt.Printf("组合折扣价格: %.2f", composite.Calculate(350)) // (350-50)*0.8=240

六、与其他模式对比

模式核心目标关键区别
状态模式对象内部状态改变行为状态转移由内部条件触发
工厂模式创建对象关注对象创建过程
模板方法算法步骤固定通过继承实现代码复用

七、总结

策略模式通过算法封装动态切换,解决了以下问题:

  1. 灵活扩展:新增策略无需修改上下文
  2. 代码复用:相同策略可被多个客户端共享
  3. 条件简化:消除复杂的if-else分支

在Go语言中实现时需注意:

  • 通过接口实现多态,而非继承
  • 使用工厂模式管理策略实例
  • 组合策略实现复杂算法叠加
  • 避免策略类过度细分(如差异过小的策略合并)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值