【最佳实践】Go 状态模式

embedded/2025/3/19 6:27:08/

设计思路

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

场景描述

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

实现示例

下面是一个使用状态模式实现的 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/embedded/173782.html

相关文章

python-leetcode 47.组合总和

题目: 给一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target所有不同组合,并以列表形式返回,可以按任意顺序返回这些组合。 candidates中的同一个数字可以无限制重复被选取,如…

防火墙双机热备(主备分担)

目录 引言 主备备份实验 1、基本配置 2、双机热备配置 查看双机热备状态 主备切换 路由影响 引言 传统VRRP方式无法实现主、备用防火墙状态信息和多组VRRP状态的一致性,所以可能会导致流量的回包不从首包通过的防火墙回包,防火墙会因为状态检测机…

【Java篇】一法不变,万象归一:方法封装与递归的思想之道

文章目录 Java 方法的使用:从基础到递归的全面解析一、方法的概念及使用1.1 什么是方法 (method)?1.2 方法定义1.3 方法调用的执行过程1.4 实参和形参的关系1.5 没有返回值的方法 二、方法重载2.1 为什么需要方法重载2.2 方法重载的概念2.2.4 C 和 Java 的比较&…

采购与供应链项目建议书(46页PPT)(文末有下载方式)

资料解读:采购与供应链项目建议书(46页PPT) 详细资料请看本解读文章的最后内容。 引言 在当今竞争激烈的市场环境中,采购与供应链管理已成为企业核心竞争力的重要组成部分。本文将对《采购与供应链项目建议书》进行详细解读&am…

linux 命令 tail

tail 是 Linux 中用于查看文件末尾内容的命令&#xff0c;常用于日志监控和大文件快速浏览。以下是其核心用法及常见选项&#xff1a; 基本语法 tail [选项] 文件名 常用选项 显示末尾行数 -n <行数> 或 --lines<行数> 指定显示文件的最后若干行&#xff08;…

Spring Boot 整合 Redis 使用教程

Redis 是一种高性能的键值存储数据库&#xff0c;常用于缓存、会话管理和消息队列等场景。Spring Boot 通过 Spring Data Redis 提供了简洁的整合方式。 1. 环境准备 1.1 添加依赖 在 pom.xml 中添加 Redis 依赖&#xff08;Spring Boot 3.x&#xff09;&#xff1a; <de…

波士顿咨询X大型制造业数字化转型战略规划项目(98页PPT)(文末有下载方式)

资料解读&#xff1a;波士顿咨询 X 大型制造业数字化转型战略规划项目&#xff08;98 页&#xff09; 详细资料请看本解读文章的最后内容。在当下数字化浪潮席卷全球的时代&#xff0c;制造业作为国家经济发展的重要支柱&#xff0c;其数字化转型进程备受关注。这份由波士顿咨…

使用Ajax技术进行动态网页的爬虫(pycharm)

Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;技术在现代Web开发中广泛应用。 它允许网页在不重新加载整个页面的情况下&#xff0c;通过JavaScript与服务器进行异步通信&#xff0c;动态更新部分内容。这种技术对爬虫的功能和作用产生了显著影响&#xff0c;…