Golang如何实现状态模式与策略模式结合

来源:AI编程作者:下班再修头衔:程序员
导读:本期聚焦于小伙伴创作的《Golang如何实现状态模式与策略模式结合》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Golang如何实现状态模式与策略模式结合》有用,将其分享出去将是对创作者最好的鼓励。

在Golang的业务开发中,状态模式和策略模式都是行为型设计模式的重要成员,二者结合使用可以很好地应对对象状态多变且不同状态下存在多种处理逻辑的场景。状态模式关注对象内部状态变化带来的行为改变,策略模式则聚焦于不同算法的封装与动态切换,将二者结合可以兼顾状态管理和算法灵活性。

Golang如何实现状态模式与策略模式结合

两种模式的核心概念

状态模式

状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来好像修改了它的类。核心是将状态相关的行为封装到独立的状态类中,当对象状态切换时,切换对应的状态类实例即可。

策略模式

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法独立于使用它的客户而变化,核心是通过接口定义算法族,运行时动态选择具体策略。

结合场景设计

我们以订单处理系统为例,订单存在待支付、已支付、待发货、已发货、已完成、已取消等多种状态,不同状态下订单的处理逻辑不同,同时部分状态下存在多种可选的处理策略,比如待支付状态下可以使用微信支付、支付宝支付等不同支付策略。

接口定义

首先定义状态接口和策略接口:

// 订单状态接口
type OrderState interface {
    // 处理订单
    HandleOrder(order *Order) error
    // 获取状态名称
    GetStateName() string
}

// 支付策略接口
type PayStrategy interface {
    // 执行支付
    Pay(amount float64) error
    // 获取策略名称
    GetStrategyName() string
}

具体状态实现

实现待支付状态,该状态下需要选择支付策略完成支付:

// 待支付状态
type WaitPayState struct {
    payStrategy PayStrategy
}

func (w *WaitPayState) SetPayStrategy(strategy PayStrategy) {
    w.payStrategy = strategy
}

func (w *WaitPayState) HandleOrder(order *Order) error {
    if w.payStrategy == nil {
        return fmt.Errorf("未设置支付策略")
    }
    err := w.payStrategy.Pay(order.Amount)
    if err != nil {
        return err
    }
    // 支付成功后切换到已支付状态
    order.SetState(&PaidState{})
    return nil
}

func (w *WaitPayState) GetStateName() string {
    return "待支付"
}

// 已支付状态
type PaidState struct{}

func (p *PaidState) HandleOrder(order *Order) error {
    // 已支付状态下触发发货逻辑
    order.SetState(&WaitDeliverState{})
    return nil
}

func (p *PaidState) GetStateName() string {
    return "已支付"
}

// 待发货状态
type WaitDeliverState struct{}

func (w *WaitDeliverState) HandleOrder(order *Order) error {
    // 执行发货逻辑
    order.SetState(&DeliveredState{})
    return nil
}

func (w *WaitDeliverState) GetStateName() string {
    return "待发货"
}

// 已发货状态
type DeliveredState struct{}

func (w *DeliveredState) HandleOrder(order *Order) error {
    // 确认收货后切换到已完成状态
    order.SetState(&FinishedState{})
    return nil
}

func (w *DeliveredState) GetStateName() string {
    return "已发货"
}

// 已完成状态
type FinishedState struct{}

func (w *FinishedState) HandleOrder(order *Order) error {
    return fmt.Errorf("订单已完成,无法处理")
}

func (w *FinishedState) GetStateName() string {
    return "已完成"
}

// 已取消状态
type CanceledState struct{}

func (w *CanceledState) HandleOrder(order *Order) error {
    return fmt.Errorf("订单已取消,无法处理")
}

func (w *CanceledState) GetStateName() string {
    return "已取消"
}

具体策略实现

实现两种支付策略:

// 微信支付策略
type WechatPayStrategy struct{}

func (w *WechatPayStrategy) Pay(amount float64) error {
    // 模拟微信支付逻辑
    fmt.Printf("使用微信支付完成支付,金额:%.2f元n", amount)
    return nil
}

func (w *WechatPayStrategy) GetStrategyName() string {
    return "微信支付"
}

// 支付宝支付策略
type AliPayStrategy struct{}

func (a *AliPayStrategy) Pay(amount float64) error {
    // 模拟支付宝支付逻辑
    fmt.Printf("使用支付宝支付完成支付,金额:%.2f元n", amount)
    return nil
}

func (a *AliPayStrategy) GetStrategyName() string {
    return "支付宝支付"
}

订单上下文实现

订单结构体作为上下文,持当前状态和订单信息:

type Order struct {
    Id     string
    Amount float64
    state  OrderState
}

func NewOrder(id string, amount float64) *Order {
    return &Order{
        Id:     id,
        Amount: amount,
        state:  &WaitPayState{},
    }
}

func (o *Order) SetState(state OrderState) {
    o.state = state
}

func (o *Order) GetStateName() string {
    return o.state.GetStateName()
}

func (o *Order) Handle() error {
    return o.state.HandleOrder(o)
}

// 待支付状态下设置支付策略的方法
func (o *Order) SetPayStrategy(strategy PayStrategy) {
    if waitPayState, ok := o.state.(*WaitPayState); ok {
        waitPayState.SetPayStrategy(strategy)
    }
}

组合使用演示

编写测试代码验证两种模式的结合效果:

func main() {
    // 创建订单
    order := NewOrder("ORD001", 199.99)
    fmt.Printf("当前订单状态:%sn", order.GetStateName())

    // 设置微信支付策略
    order.SetPayStrategy(&WechatPayStrategy{})
    // 处理订单(支付)
    err := order.Handle()
    if err != nil {
        fmt.Printf("处理失败:%vn", err)
        return
    }
    fmt.Printf("当前订单状态:%sn", order.GetStateName())

    // 继续处理订单(发货)
    err = order.Handle()
    if err != nil {
        fmt.Printf("处理失败:%vn", err)
        return
    }
    fmt.Printf("当前订单状态:%sn", order.GetStateName())

    // 继续处理订单(确认收货)
    err = order.Handle()
    if err != nil {
        fmt.Printf("处理失败:%vn", err)
        return
    }
    fmt.Printf("当前订单状态:%sn", order.GetStateName())

    // 已完成状态下再次处理
    err = order.Handle()
    if err != nil {
        fmt.Printf("处理失败:%vn", err)
    }
}

实践总结

通过上面的实现可以看到,状态模式负责订单状态的流转和不同状态下的行为封装,策略模式负责待支付状态下不同支付方式的算法封装,二者结合既保证了状态管理的清晰性,又保证了支付逻辑的扩展性。如果后续需要新增支付方式,只需要新增策略实现即可,不需要修改状态类的代码;如果需要新增订单状态,只需要新增状态实现并调整状态流转逻辑即可,符合开闭原则。

Golang状态模式策略模式设计模式修改时间:2026-06-27 13:21:19

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。