当前位置: 首页 > article >正文

《golang设计模式》第三部分·行为型模式-08-状态模式(State)

文章目录

  • 1. 概念
    • 1.1 作用
    • 1.1 角色
    • 1.2 类图
  • 2. 代码示例
    • 2.1 设计
    • 2.2 代码
    • 2.3 类图

1. 概念

1.1 作用

状态(State)指状态对象,用于封装上下文对象的特定状态行为,使得上下文对象在内部状态改变时能够改变其自身的行为。

1.1 角色

  • Context(环境类角色):内部维护一个当前状态实例,并负责具体状态的切换。
  • State(抽象状态角色):
    • 是所有具体状态的抽象接口
    • 它的每一个方法代表了环境类的一种操作
  • ConcreteState(具体状态角色):
    • 每个ConcreteState都代表了环境类的一个状态
    • 它的每一个方法代表了环境类在该状态下的一种行为(环境在不同状态下,同一行为的操作是不同的)

1.2 类图

Context
-state:State
+behavior()
«interface»
State
+Handle(con:Context)
StateA
+Handle(con:Context)
StateB
+Handle(con:Context)
StateC
+Handle(con:Context)

2. 代码示例

2.1 设计

需求

  • 环境有关闭、受限、正常三个状态
  • 环境有查看、评论、发布三种状态
  • 其对应关系如下:
查看评论发布
正常
受限×
关闭×××
  • 定义环境类Context
    • 它依赖了抽象状态(如果状态没有冲突,你也可以写成状态的聚合)
    • 它有一个成员是健康值
    • 它的一个内部方法,用来修改状态(虽然golang没有java对类的权限控制,我们只能这么理解,尽量不在“类之外调用”)
    • 它的一个外部方法,传入健康值同时修改环境状态
  • 定义一个函数,创建环境类(这不是状态模式的重点,仅为了方便实例化)
  • 定义抽象状态State
  • 定义一个具体状态关闭(模拟一个网站的用户状态)
    • 它的View()方法,模式关闭状态用户不能查看
    • 它的Comment()方法,模拟关闭状态用户不能评论
    • 它的Post()方法,模拟关闭状态用户不能发布
  • 定义一个具体状态限制(模拟一个网站的用户状态)
    • 它的View()方法,模式限制状态用户可以查看
    • 它的Comment()方法,模拟限制状态用户可以评论
    • 它的Post()方法,模拟限制状态用户不能发布
  • 定义一个具体状态正常(模拟一个网站的用户状态)
    • 它的View()方法,模式正常状态用户可以查看
    • 它的Comment()方法,模拟正常状态用户可以评论
    • 它的Post()方法,模拟正常状态用户可以发布
  • 调用
    • 实例化一个环境类
    • 执行查看操作
    • 修改环境类健康值
    • 再次执行查看操作

2.2 代码

  • 代码
package main

import (
	"fmt"
)

// 定义环境类
type Context struct {
	state       State
	HealthValue int
}

// 根据环境类健康值修改环境状态
func (c *Context) changeState() {
	if c.HealthValue <= -10 {
		c.state = &Close{}
	} else if c.HealthValue > -10 && c.HealthValue <= 0 {
		c.state = &Restriction{}
	} else if c.HealthValue > 0 {
		c.state = &Normal{}
	}
}

// 设置环境类健康值
func (c *Context) SetHealth(value int) {
	c.HealthValue = value
	c.changeState()
}

// 创建环境类
func CreateContext(health int) *Context {
	a := &Context{
		HealthValue: health,
	}
	a.changeState()
	return a
}

// 定义抽象状态类
type State interface {
	View()
	Comment()
	Post()
}

// 定义第一个具体状态
type Close struct{}

func (c *Close) View() {
	fmt.Println("无法查看")
}

func (c *Close) Comment() {
	fmt.Println("不能评论")
}

func (c *Close) Post() {
	fmt.Println("不能发布")
}

// 定义第二个具体状态
type Restriction struct{}

func (r *Restriction) View() {
	fmt.Println("查看正常")
}

func (r *Restriction) Comment() {
	fmt.Println("评论正常")
}

func (r *Restriction) Post() {
	fmt.Println("不能发布")
}

// 定义第三个具体状态
type Normal struct{}

func (n *Normal) View() {
	fmt.Println("查看正常")
}

func (n *Normal) Comment() {
	fmt.Println("评论正常")
}

func (n *Normal) Post() {
	fmt.Println("发布正常")
}

func main() {
	context := CreateContext(75)
	context.state.View()

	fmt.Println("================改变健康值==========")
	context.SetHealth(-20)
	context.state.View()
}
  • 输出
查看正常
================改变健康值==========
无法查看

2.3 类图

Context
-state State
+ Int HealthValue
+SetHealth(value int)
-changeState()
«interface»
State
+View()
+Comment()
+Post()
Close
+View()
+Comment()
+Post()
Restriction
+View()
+Comment()
+Post()
Normal
+View()
+Comment()
+Post()

http://www.kler.cn/a/148558.html

相关文章:

  • 【算法】——二分查找合集
  • 利用滑动窗口解题
  • Openstack7--安装消息队列服务RabbitMQ
  • 应用程序部署(IIS的相关使用,sql server的相关使用)
  • Java 网络编程(一)—— UDP数据报套接字编程
  • AI绘画经验(stable-diffusion)
  • LeetCode-面试题08.01 三步问题 C/C++实现 超详细思路及过程[E]
  • 【云栖 2023】姜伟华:Hologres Serverless 之路——揭秘弹性计算组
  • MySQL学习day03
  • 9.增删改操作
  • [autojs]ui线程中更新控件的值的问题
  • 中小型公司如何搭建运维平台,rancher、kubersphere、rainbond
  • 漏洞环境靶场搭建(内含DVWA SQLi-LABS upload-labs等)
  • mybatis <include refid=“xxx“></include>
  • 【每日一题】1457. 二叉树中的伪回文路径-2023.11.25
  • 142. 环形链表 II --力扣 --JAVA
  • linux 提权
  • XML Schema中的simpleContent 元素
  • os和path模块
  • NI自动化测试系统用电必备攻略,电源规划大揭秘
  • 成为AI产品经理——TPR、FPR、ROC、AUC
  • vue3-09
  • 5.28每日一题(函数在区间有/无界的判断:相关定理(充分条件))
  • Kanna库代码示例
  • 股票技术从初级到高级,从实盘进阶到摩尔缠论
  • Unity优化——脚本优化策略3