【最佳实践】Go 状态模式

devtools/2025/3/19 8:58:12/

设计思路

状态模式的核心在于将对象的行为封装在特定的状态类中,使得对象在不同的状态下表现出不同的行为。每个状态实现同一个接口,允许对象在运行时通过改变其内部状态对象来改变其行为。状态模式使得状态转换更加明确,并且易于扩展新的状态和行为。

场景描述

假设我们有一个简单的文档编辑器,文档可以处于不同的编辑状态:草稿、审核、发布。每个状态对应不同的行为,比如在草稿状态下可以编辑内容,在审核状态下可以提交审核,在发布状态下可以查看内容但不能编辑。我们将使用状态模式来实现这一场景。

实现示例

下面是一个使用状态模式实现的 Go 语言示例,展示了一个简单的文档编辑系统:

package mainimport "fmt"// DocumentState 是状态接口,定义了文档状态的行为
type DocumentState interface {Edit() uiltin">errorSubmit() uiltin">errorPublish() uiltin">error
}// Document 是包含状态的上下文
type Document struct {state DocumentState
}// SetState 设置文档的当前状态
func (d *Document) SetState(state DocumentState) {d.state = state
}// Edit 触发编辑行为
func (d *Document) Edit() uiltin">error {return d.state.Edit()
}// Submit 触发提交审核行为
func (d *Document) Submit() uiltin">error {return d.state.Submit()
}// Publish 触发发布行为
func (d *Document) Publish() uiltin">error {return d.state.Publish()
}// DraftState 是草稿状态
type DraftState struct {document *Document
}func (s *DraftState) Edit() uiltin">error {fmt.Println("Editing the document.")return nil
}func (s *DraftState) Submit() uiltin">error {fmt.Println("Submitting the document for review.")s.document.SetState(&ReviewState{document: s.document})return nil
}func (s *DraftState) Publish() uiltin">error {return fmt.Errorf("document cannot be published directly from draft")
}// ReviewState 是审核状态
type ReviewState struct {document *Document
}func (s *ReviewState) Edit() uiltin">error {return fmt.Errorf("document cannot be edited during review")
}func (s *ReviewState) Submit() uiltin">error {return fmt.Errorf("document is already under review")
}func (s *ReviewState) Publish() uiltin">error {fmt.Println("Publishing the document.")s.document.SetState(&PublishedState{document: s.document})return nil
}// PublishedState 是已发布状态
type PublishedState struct {document *Document
}func (s *PublishedState) Edit() uiltin">error {return fmt.Errorf("document cannot be edited after publishing")
}func (s *PublishedState) Submit() uiltin">error {return fmt.Errorf("document is already published")
}func (s *PublishedState) Publish() uiltin">error {fmt.Println("Document is already published.")return nil
}func main() {// 创建一个文档,并设置初始状态为草稿document := &Document{}initialState := &DraftState{document: document}document.SetState(initialState)// 编辑文档err := document.Edit()if err != nil {fmt.Println("Error:", err)}// 提交文档审核err = document.Submit()if err != nil {fmt.Println("Error:", err)}// 尝试编辑文档(应失败,因为在审核中)err = document.Edit()if err != nil {fmt.Println("Error:", err)}// 发布文档err = document.Publish()if err != nil {fmt.Println("Error:", err)}// 尝试发布文档(应成功,因为已发布)err = document.Publish()if err != nil {fmt.Println("Error:", err)}
}

代码解释

  • DocumentState 接口:定义了文档状态的行为接口,包括 EditSubmitPublish 方法。每个状态实现这些行为。

  • Document 结构体:代表文档对象,包含一个 DocumentState。通过 SetState 方法可以改变文档的状态。

  • DraftState、ReviewState、PublishedState:分别实现了 DocumentState 接口,表示文档的不同状态。每个状态根据其特性实现了相应的行为。

  • main 函数:演示了如何使用状态模式管理文档的状态转换。文档初始状态为草稿,可以编辑和提交审核;审核状态下可以发布;发布状态下可以查看,但不能编辑或再次发布。

总结

状态模式」抽象过程的核心是:

  • 每一个状态映射对应行为
  • 行为实现同一个接口interface
  • 行为是内部的一个状态
  • 状态是不断变化的

http://www.ppmy.cn/devtools/168295.html

相关文章

蓝桥杯学习-01好数

01枚举 1.好数 问题描述 一个整数如果按从低位到高位的顺序,奇数位 (个位、百位、万位 ⋯⋯ ) 上的数字是奇数,偶数位 (十位、千位、十万位 ⋯⋯ ) 上的数字是偶数,我们就称之为 “好数”。 给定一个正整数 NN,请计算从 1 到 …

NAT技术-初级总结

NAT–网络地址转换 NAT基本逻辑是实现公网IP地址和私网IP地址的转换 华为设备所有NAT相关的配置都是在边界路由器的出接口上配置 1.静态NAT–一对一 就是在我们私网边界路由器上建立维护一张静态地址映射表,这张表 反映的是公网IP地址和私网IP地址之间一一对应的关系 只能一个…

[K!nd4SUS 2025] Crypto

最后一个把周末的补完。这个今天问了小鸡块神终于把一个补上,完成5/6,最后一个网站也上不去不弄了。 Matrices Matrices Matrices 这个是不是叫LWE呀,名词忘了,但意思还是知道。 b a*s e 这里的e是高斯分成,用1000…

使用Azure CDN进行子域名接管

目录: 寻找子域名 寻找潜在的子域名接管 创建 PoC(概念验证) 本文的重点描述我发现的一起利用 Microsoft Azure 的 CDN (azureedge.net) 实现的子域名接管案例。我使用自己的域名重现了该问题,并会介绍我发现它的过程以及如何创建…

Qwen2.5-VL 开源视觉大模型,模型体验、下载、推理、微调、部署实战

一、Qwen2.5-VL 简介 Qwen2.5-VL,Qwen 模型家族的旗舰视觉语言模型,比 Qwen2-VL 实现了巨大的飞跃。 欢迎访问 Qwen Chat (Qwen Chat)并选择 Qwen2.5-VL-72B-Instruct 进行体验。 1. 主要增强功能 1)直观地理解事物&…

【后端开发面试题】每日 3 题(十三)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:https://blog.csdn.net/newin2020/category_12903849.html 📚专栏简介:在这个专栏中,我将会分享后端开发面试中常见的面试题给大家,每天的题目都是独…

深搜专题9:取数游戏

输入描述 第一行有一个正整数 T,表示了有 T 组数据。 对于每一组数据,第一行有两个正整数 N 和 M,表示了数字矩阵为 N 行 M 列。 接下来 N 行,每行 M 个非负整数,描述了这个数字矩阵。 对于20%的数据,1…

核心期刊指的是哪些“核心”?

“核心期刊”是中国学术界对高质量学术期刊的统称,其认定依托于不同评价机构建立的遴选体系。目前国内公认的“核心”主要指以下四类体系: 1. 北大核心(中文核心期刊要目总览) 由北京大学图书馆联合多所高校研制,…