策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。

使用背景

  1. 行为的变化:当一个类的行为取决于它的状态,并且它在运行时可以根据不同的状态改变它的行为时,就可以考虑使用策略模式。通过定义不同的策略类来表示不同的状态或行为,可以使得类的行为更加灵活可变。
  2. 避免条件语句过多:当一个类的某些方法包含大量的条件语句,并且随着条件的增加而变得复杂时,可以使用策略模式来避免条件语句的过多使用。将不同的条件逻辑封装在不同的策略类中,可以使得代码更加清晰、可维护和可扩展。
  3. 行为的独立性:当需要将算法的实现与调用者解耦,使得算法的实现可以独立于调用者而变化时,可以使用策略模式。通过将算法封装在独立的策略类中,并将策略类注入到调用者中,可以实现算法和调用者的解耦。
  4. 可复用的算法:当有一些算法可能被多个类或模块使用,并且这些算法可能会发生变化时,可以使用策略模式。通过将算法封装在策略类中,并且可以在不同的上下文中共享使用,可以实现算法的复用。
  5. 动态切换算法:当需要在运行时根据不同的情况选择不同的算法时,可以使用策略模式。通过将不同的算法封装在不同的策略类中,并在运行时根据需要动态切换策略类,可以实现动态选择算法的功能。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package main

import "fmt"

// DiscountStrategy 定义了打折策略接口
type DiscountStrategy interface {
ApplyDiscount(price float64) float64
}

// NoDiscountStrategy 不打折策略
type NoDiscountStrategy struct{}

func (nds *NoDiscountStrategy) ApplyDiscount(price float64) float64 {
return price
}

// TwentyPercentDiscountStrategy 20% 折扣策略
type TwentyPercentDiscountStrategy struct{}

func (tds *TwentyPercentDiscountStrategy) ApplyDiscount(price float64) float64 {
return price * 0.8
}

// FiftyPercentDiscountStrategy 50% 折扣策略
type FiftyPercentDiscountStrategy struct{}

func (fds *FiftyPercentDiscountStrategy) ApplyDiscount(price float64) float64 {
return price * 0.5
}

// Context 上下文,包含了当前使用的打折策略
type Context struct {
discountStrategy DiscountStrategy
}

// NewContext 创建上下文对象
func NewContext(discountStrategy DiscountStrategy) *Context {
return &Context{discountStrategy: discountStrategy}
}

// SetDiscountStrategy 设置打折策略
func (c *Context) SetDiscountStrategy(discountStrategy DiscountStrategy) {
c.discountStrategy = discountStrategy
}

// GetDiscountPrice 获取打折后的价格
func (c *Context) GetDiscountPrice(price float64) float64 {
return c.discountStrategy.ApplyDiscount(price)
}

func main() {
// 创建上下文对象,并设置不同的打折策略
context := NewContext(&NoDiscountStrategy{})
fmt.Println("无折扣价格:", context.GetDiscountPrice(100))

context.SetDiscountStrategy(&TwentyPercentDiscountStrategy{})
fmt.Println("20% 折扣价格:", context.GetDiscountPrice(100))

context.SetDiscountStrategy(&FiftyPercentDiscountStrategy{})
fmt.Println("50% 折扣价格:", context.GetDiscountPrice(100))
}

结语

策略模式通过将算法封装成独立的策略类,并将策略类注入到调用者中,可以实现算法和调用者的解耦,同时避免了大量的条件语句,提高了代码的可读性和可维护性。
在使用策略模式时,需要注意选择合适的策略类和上下文类,以及合适的策略切换方式,以满足系统的需求并且保持代码的简洁和清晰。策略模式适用于各种需要根据不同情况选择不同算法或行为的场景,如商业规则引擎、优化算法、游戏 AI 策略等。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。