前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈模式之状态模式

漫谈模式之状态模式

作者头像
孟君
发布2023-03-23 08:58:51
2370
发布2023-03-23 08:58:51
举报
文章被收录于专栏:孟君的编程札记

今天,我们来分享行为型模式的另外一个成员:状态模式

状态模式是一种行为型模式,它允许对象在其内部状态发生变化时改变其行为。状态模式的核心思想是将对象的状态封装成一个独立的类,并将状态转移的逻辑委托给状态类来处理,从而使得对象在不同的状态下表现出不同的行为。

状态在我们的生活中无处不在。比如,听音乐的时候,我们可以选择不同的播放状态,可以是顺序播放、可以是单曲播放、也可以随机播放等;又如:线上购物后,订单从提交到完成也会有很多的状态变化,如下图所示:(当然中间可能涉及到退货等导致状态变化的,这里不展开说)。

图片
图片

再比如:一个TCP连接可以有Open、Acknowledge、Close等状态,一旦状态改变其行为也将发生变化。今天我们就来看一下一个状态改变后行为发生改变的模式 -- 状态模式。

状态模式的基本介绍

意图

允许一个对象在其内部状态改变的时候改变它的行为。对象看起来似乎修改了它的类。

结构

状态模式的基本结构如下:

图片
图片

这里涉及到的参与者有如下几种:

Context(环境)

  • 定义客户感兴趣的接口。
  • 维护一个ConcreteState子类的实例,这个实例定义当前的状态。

State(状态)

  • 定义一个接口以封装与Context的特定状态相关的行为。

ConcreteState(具体子类)

  • 每个子类实现一个与Context的一个状态相关的行为。

参与者如何协作?

1、Context将与状态相关的请求委托给当前的ConreteState对象处理

2、Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。

3、Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不在需要直接与状态对象打交道。

4、Context或者ConcreteState子类都可以决定哪个状态是另外一个状态的后继者,以及是在何种条件下进行状态转换。

状态模式的示例

接下来,我们模拟监听目录查看是否有对账文件到达。

如对账文件到达,则我们开启对账处理流程,经历文件达到状态、准备数据状态、处理中状态以及完成对账状态4个阶段,不同状态下处理不同的逻辑。

我们使用状态模式来做下处理。

抽象状态接口

图片
图片

具体的状态(4个)

图片
图片

上下文环境

图片
图片

客户端Client

图片
图片

结果输出

图片
图片

这样,一个简单的状态模式示例就完成了。

小结

状态模式使用场景

在以下情况下可以使用状态模式:

  • 一个对象的行为依赖于它所处的状态,对象的行为必须随着状态的改变而改变。
  • 对象在某个方法里依赖于一重或者多重的条件转移语句,其中有大量的代码。状态模式把条件转移语句的每一个分支都包装到一个单独的类里。这使得这些条件转移分支能够以类的方式独立存在和演化。维护这些独立的类也就不再影响到系统的其他部分。

状态模式 vs. 策略模式

状态模式

将一群行为封装到状态类中,主类的当前状态在状态集合中游走,随着时间的流逝,主类的行为不断变化,但这对客户端而言完全是透明的,而策略模式需要客户端明确所有策略,以指明一个具体的策略。

策略模式

定义一组 算法实现,实现之间可以任意替换,而且可以在运行时动态的选择任意一种实现。 需要客户端清楚所有的策略以选择合适的策略。

如何选择?

状态模式和策略模式很相像,容易混淆,但两者意图不同。有的时候很难区分应当使用状态模式还是应当使用策略模式。一个简单的方法便是考察环境角色是否有明显的状态和状态的过渡。如果环境角色只有一个状态,那么就应当使用策略模式。而状态模式则适用于另一种情况,即环境角色有明显的状态转移。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 状态模式的基本介绍
  • 状态模式的示例
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档