问题标签 [state-pattern]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
3831 浏览

c++ - 如何避免沮丧?

我有一个状态模式的实现,其中每个状态都处理它从事件队列中获取的事件。因此基State类有一个纯虚方法void handleEvent(const Event*)。事件继承基Event类,但每个事件都包含其可以是不同类型的数据(例如,int、string...或其他)。handleEvent必须确定接收到的事件的运行时类型,然后执行向下转换以提取事件数据。事件是动态创建并存储在队列中的(因此在这里进行向上转换......)

我知道向下转换是糟糕设计的标志,但在这种情况下是否可以避免它?我正在考虑访问者模式,其中基类 State 将包含每个事件的虚拟处理程序,但是再次向下转换将需要发生在从队列中取出事件并将其传递到当前状态的代码段中。(至少在这种情况下,大switch(eventID)只会在一个地方......)。访客模式是避免向下转换的最佳方式(最佳实践)吗?

这是伪代码(我boost::shared_ptr在这个例子中传递,但无论如何都会发生向下转换):

0 投票
2 回答
3774 浏览

design-patterns - 状态模式与 ENUM

有时需要为对象的状态提供支持。据我了解,有两种方法:

  1. 枚举(简单)
  2. STATE模式(OC原理)

很明显,需要为此目的使用状态模式(我不确定)。

但是阅读我经常面对的其他代码只是枚举而不是状态模式。状态模式有权力吗?

0 投票
3 回答
1600 浏览

oop - 替代(或改进)遭受 LSP 违规的状态模式

对于我们目前正在构建的发票系统,我很难理解基于状态的功能。该系统将支持发票的计算、人工审批、打印和存档。

起初我认为我们应该使用状态模式来对此进行建模。发票将是上下文,它将打印、归档等委托给其当前分配的状态。

但这显然是个坏主意,因为不同的状态(创建、批准、打印、存档)不应该支持相同的操作。例如,您不应该能够打印以前未经批准的发票。为不受支持的操作抛出异常将违反 LSP。我在这里找到了这个问题的一般描述。

有没有人有想法,如何适当地实施这个?


PS:我知道这听起来像是一些蹩脚的家庭作业,但事实并非如此;我需要这个用于现实世界的系统。

0 投票
2 回答
4311 浏览

java - 使用状态模式设计在 Java 中实现通信协议

如果在其他地方回答了这个问题,我们深表歉意;找不到足够的信息来说服自己最好的方法来做到这一点。我也意识到这是一个没有代码的冗长解释,但请告诉我是否应该编写一些示例代码来帮助演示我在做什么。

基本上:

  • 使用 System.in/out 在 Java 中实现通信协议
  • 当前的方法是实现一种状态模式,其中在上下文类中的 System.in 上实例化 Scanner
  • 具体状态调用上下文方法从 Scanner 读取,然后根据 Scanner 返回的值适当地执行操作/转换状态

我使用状态模式的初衷是在从 System.in 解析这样的序列时简化代码(不要询问语法,这是我必须使用的东西):

  • 命令名称=X
  • 标题
  • 标题信息行
  • 内容
  • 命令内容行
  • 结束内容
  • 结束命令

我通常为我期望收到的每种类型的命令定义一个具体的状态。以上述序列为例,我将有一个类似于 {WAITING_FOR_COMMAND, COMMAND_RECEIVED, PARSING_HEADER, PARSING_CONTENTS, PARSING_DONE, COMMAND_PROCESSED} 的状态集。我最初会在 WAITING_FOR_COMMAND,然后当收到“COMMAND NAME=X”时,我会转换到 COMMAND_RECEIVED,然后当“HEADER”进来时,我会转换到 PARSING_HEADER,等等。这种设计使得遍历所有边缘情况协议更容易,并且还使代码在协议被调整时易于更新/维护。显然比大量的 switch 语句和重复的边界检查要好得多。

我遇到的问题是,当我充实我的具体状态行为时,我发现自己在上下文类中声明了越来越多的状态变量,并且知道这可能很糟糕,因为我正在创建非常暴露的接口和非常高的联系上下文和具体的状态类。该协议中的命令序列可以任意长,我需要保存命令序列中每个项目传递的信息,直到命令序列完成。

以上面的命令序列为例,在“COMMAND ID=X”之后,我想在收到“ENDCOMMAND”并完全处理命令后保存值X以备将来使用。在“HEADER”之后,我想在收到“ENDCOMMAND”后保存标题信息以备将来使用,以供实际处理命令时使用。等等等等。现在只需将 commandId 和标头状态变量添加到上下文类中就可以了,但对我来说似乎并不干净或封装得很好。

有没有人对他们如何解决这个问题有任何高层次的建议?有没有更好的使用状态设计模式呢?

只是要注意一些我一直在玩的想法:

  • 为每种类型的命令序列定义状态上下文,并在从 System.in 接收到相关命令时调用适当的上下文;这看起来几乎就像拥有巨大的开关块一样混乱,并且似乎过度复杂化了设计
  • 设计支持复合 FSM 的成熟 FSM 架构,其中每个命令序列在总体 FSM 中占据其自己的 FSM;这对我来说似乎有点矫枉过正
  • 为每个命令序列类型创建具有各种子类的 ProtocolCommand 对象;我可以在转换时将这些传递到每个状态,并在我进行过程中逐渐建立它们……但这会使状态接口变得混乱,并迫使所有状态摄取一个他们不一定会使用的参数

非常感谢!抱歉,这太冗长了,如果我能澄清什么,请告诉我。

0 投票
5 回答
1038 浏览

gwt - 解耦 GWT 异步回调

我有以下问题:我正在尝试使用 GWT 对流程进行建模,其中我有几个带有几个提交按钮的视图。按下 button1 将创建一个服务器交互,如果一切正常,将加载下一个视图。我现在的问题是我得到了非常讨厌的意大利面条代码(只是非常高级以向您展示我的意思):

有什么方法可以创建某种抽象或其他东西吗?也许是状态模式?如何?非常感谢!

0 投票
1 回答
1384 浏览

oop - 状态模式似乎使用循环引用。为什么这样可以?

我仍在尝试了解循环引用的危险。我经常读到它们只应在极少数情况下使用。但是,在规范的状态模式中,“状态”对象需要引用“上下文”对象才能引起转换,“上下文”对象需要引用“状态”对象才能触发它们的行为。

这不是循环引用吗?如果不是,它与循环引用有何关系?如果是这样,为什么这是可以接受的?

http://en.wikipedia.org/wiki/State_pattern

http://sourcemaking.com/design_patterns/state

0 投票
2 回答
312 浏览

c++ - 如何确定状态模式的状态

我正在开发一个 DLL,用于通过 LAN 控制 POS(销售点)终端。

DLL 提供了执行以下操作的命令:

  • 登录
  • 注销
  • 授权
  • 读卡数据
  • 消除
  • 退款
  • 网络诊断

DLL 还提供 Connect() 和 Disconnect() 函数。

由于 POS 终端可以处于各种状态,我认为状态模式可能会在 DLL 中使用。

伪代码:

PosLoggedon和PosLoggedoff都是我认为有效的两个状态,但我不确定如何确定其他状态。

创建像PosAuthorisationPosReadCardData等状态以便它们对应于 POS 函数是否有意义?大概没有意义吧……

我对如何正确使用状态模式感到困惑,因为我正在混合“当前命令进行中”和“当前 POS 状态”。

也许我需要像PosCommandInProgress这样的状态?

任何意见,将不胜感激。

非常感谢。

0 投票
1 回答
1342 浏览

java - 安卓的枚举状态模式

我正在尝试创建一个 Enum STATE 模式,以便我可以设置我的操作的当前状态。在 C# 中(我认为)我使用了这种模式:

我确实在某个地方读到了您不应该或不能在 Android 中使用 Enum 的内容。如何在 Android 中复制这种设计模式?

0 投票
1 回答
317 浏览

tcp - 给定 TCP,当 IO 是非阻塞时,状态设计模式是不是没什么用处?

在我的 TCP 应用程序中,只要 IO 处于阻塞状态,State 设计模式似乎就很有用。

我的 SwingWorker 的 doInBackground() 可以通过引用一个对象来循环读取、写入和接受 TCP 连接中的状态。请参阅维基百科讨论页上的示例:http ://en.wikipedia.org/wiki/Talk%3AState_pattern 。

但是,当我将服务器重构为非阻塞 IO 时,它似乎不再有用。Select() 返回一组为 IO 准备的通道,这些通道通过引用一系列 if 语句中的 SelectionKey 状态来处理。

任何人都可以根据经验或理解当 IO 非阻塞时状态设计模式是否仍然有用?

我问是因为我不确定我是否正确掌握了状态设计模式和 TCP 的关系。

0 投票
3 回答
1881 浏览

java - 处理状态转换的模式

我正在设计一个游戏,它会通过一些状态进行转换,我已经看到使用了两种模式,一种如下:

1)枚举模式,其中:

2)类中的状态模式,你有一个抽象,以及扩展抽象并代表每个状态的子类......单态模式?

我在两者之间有点纠结,看起来都是很好的解决方案,对于游戏来说,什么更干净更容易理解?

我个人喜欢单态,但枚举方法似乎是这样。