元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
设计原则
单一职责原则
开闭原则
里氏替换原则
依赖倒置原则
接口隔离原则
迪米特法则
▶
创建型模式
工厂方法模式
抽象工厂
单例模式
建造者模式
原型模式
▶
结构型模式
适配器模式
装饰器模式
代理模式
外观模式
组合模式
桥接模式
享元模式
▶
行为型模式
策略模式
观察者模式
命令模式
模板方法模式
状态模式
责任链模式
迭代器模式
中介者模式
访问者模式
备忘录模式
解释器模式
发布时间:
2025-03-21 15:22
↑
☰
# 策略模式 ## 概述 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户端而变化。 ## 问题场景 在软件开发中,我们经常会遇到以下场景: 1. 一个系统需要动态地在几种算法中选择一种 2. 有许多类,它们的区别仅在于它们的行为 3. 算法需要自由切换 ## 解决方案 策略模式通过以下方式解决这些问题: ```mermaid classDiagram class Context { -strategy: Strategy +setStrategy(Strategy) +executeStrategy() } class Strategy { <<interface>> +execute() } class ConcreteStrategyA { +execute() } class ConcreteStrategyB { +execute() } class ConcreteStrategyC { +execute() } Context o-- Strategy Strategy <|.. ConcreteStrategyA Strategy <|.. ConcreteStrategyB Strategy <|.. ConcreteStrategyC ``` 主要角色: 1. 策略(Strategy): 定义所有支持的算法的公共接口 2. 具体策略(ConcreteStrategy): 实现了Strategy接口的具体算法 3. 上下文(Context): 持有一个Strategy的引用 ## 代码示例 ### 1. 基本实现 ```go // Strategy 策略接口 type Strategy interface { Execute() string } // ConcreteStrategyA 具体策略A type ConcreteStrategyA struct{} func (s *ConcreteStrategyA) Execute() string { return "Executing strategy A" } // ConcreteStrategyB 具体策略B type ConcreteStrategyB struct{} func (s *ConcreteStrategyB) Execute() string { return "Executing strategy B" } // Context 上下文 type Context struct { strategy Strategy } func NewContext(strategy Strategy) *Context { return &Context{strategy: strategy} } func (c *Context) SetStrategy(strategy Strategy) { c.strategy = strategy } func (c *Context) ExecuteStrategy() string { return c.strategy.Execute() } ``` ### 2. 实际应用示例 ```go // 以支付方式为例 // PaymentStrategy 支付策略接口 type PaymentStrategy interface { Pay(amount float64) string } // CreditCardPayment 信用卡支付 type CreditCardPayment struct { cardNumber string cvv string } func NewCreditCardPayment(cardNumber, cvv string) PaymentStrategy { return &CreditCardPayment{ cardNumber: cardNumber, cvv: cvv, } } func (c *CreditCardPayment) Pay(amount float64) string { return fmt.Sprintf("Paid %.2f using Credit Card", amount) } // PayPalPayment PayPal支付 type PayPalPayment struct { email string } func NewPayPalPayment(email string) PaymentStrategy { return &PayPalPayment{email: email} } func (p *PayPalPayment) Pay(amount float64) string { return fmt.Sprintf("Paid %.2f using PayPal", amount) } // WeChatPayment 微信支付 type WeChatPayment struct { id string } func NewWeChatPayment(id string) PaymentStrategy { return &WeChatPayment{id: id} } func (w *WeChatPayment) Pay(amount float64) string { return fmt.Sprintf("Paid %.2f using WeChat Pay", amount) } // PaymentContext 支付上下文 type PaymentContext struct { strategy PaymentStrategy } func NewPaymentContext(strategy PaymentStrategy) *PaymentContext { return &PaymentContext{strategy: strategy} } func (c *PaymentContext) SetStrategy(strategy PaymentStrategy) { c.strategy = strategy } func (c *PaymentContext) ExecutePayment(amount float64) string { return c.strategy.Pay(amount) } // 使用示例 func main() { // 创建支付上下文 context := NewPaymentContext(NewCreditCardPayment("1234-5678", "123")) // 使用信用卡支付 fmt.Println(context.ExecutePayment(100.00)) // 切换到PayPal支付 context.SetStrategy(NewPayPalPayment("user@example.com")) fmt.Println(context.ExecutePayment(50.00)) // 切换到微信支付 context.SetStrategy(NewWeChatPayment("wx123456")) fmt.Println(context.ExecutePayment(200.00)) } ``` ## 适用场景 1. 算法的自由切换 - 需要在运行时选择算法的场景 - 需要动态改变对象的行为 2. 避免使用多重条件 - 有许多条件语句来选择不同的算法 - 不同的行为堆砌在一个类中 3. 数据结构和算法分离 - 算法需要独立于使用它的数据 - 需要封装算法的细节 ## 优缺点 ### 优点 1. 算法可以自由切换 - 在运行时切换算法 - 提供了灵活性 2. 避免使用多重条件判断 - 消除了条件语句 - 提高了代码的可维护性 3. 扩展性好 - 易于增加新的策略 - 符合开闭原则 ### 缺点 1. 策略类数量增加 - 每个策略都需要一个类 - 可能导致类数量过多 2. 客户端必须知道所有策略 - 需要了解所有策略的区别 - 增加了使用难度 ## 实现要点 1. 策略的选择 - 根据实际需求选择策略 - 考虑策略的可扩展性 2. 策略的封装 - 封装算法的变化 - 保持接口的稳定 3. 上下文的设计 - 管理策略对象 - 提供统一的接口 ## 相关模式 1. 工厂模式 - 可以用于创建策略对象 - 封装策略的创建过程 2. 状态模式 - 与策略模式结构类似 - 但状态模式更注重状态转换 3. 命令模式 - 都封装了行为 - 但命令模式更注重行为的执行 ## 总结 策略模式是一种行为型设计模式,它通过定义一系列算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式的核心价值在于: 1. 行为的封装 - 将算法封装在独立的类中 - 使得算法可以独立于使用它的客户端 2. 行为的切换 - 在运行时动态改变对象的行为 - 提供了更大的灵活性 3. 代码的组织 - 更好的代码组织方式 - 提高了代码的可维护性和可扩展性 在实际开发中,策略模式常用于处理算法的变化,例如排序算法、支付方式、验证方法等场景。通过策略模式,我们可以更好地管理这些变化,使代码更加清晰和易于维护。