复杂对象的状态管理是否有任何数学方法?

5
我通常使用ASP.net web forms来创建GUI,这可能是最“有状态”的技术之一。但是,它适用于任何具有状态的技术。有时候表单会很棘手和复杂,有超过30个元素和每个元素超过3种状态。直觉设计这样的表单通常适用于90%。其他10%通常需要测试人员或最终用户:)。
我认为问题在于我们应该想象同一对象上的许多情景,这比独立操作的结果要困难得多。
从函数式编程课程中,我知道最好的方法是不使用状态管理,而是使用纯函数和按值传递变量等所有这些被大大规范化的方法。有时候,我们无法避免使用状态。
您是否使用任何数学形式主义和方法来管理复杂对象的状态?不像Haskell中的monads,而是可以在更传统的业务应用程序和语言(如Java、C#、C ++)中使用的方法。
它可能不是图灵完备的形式主义,但99%也很棒:)。
如果这只是另一个荒漠问题,那么很抱歉:)

你是在询问是否使用有限状态自动机来规划 GUI 中的状态变化?你是在寻找这个吗?http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf 还是它的 UML 版本? - S.Lott
是的,当然我考虑过类似的东西。但我寻求的是这种形式主义在日常任务中的实际应用。你看到的那个太抽象了,不能直接应用。我稍后会阅读它,但从第一眼看来,它需要更多的努力才能获得微不足道的收益。我仍然不知道是否有任何严格的答案来回答我的问题。 - rudnev
@rudnev:如果您将标准方法视为“不适用于直接使用”,那么您可能找不到任何答案。 - S.Lott
我并不完全否定它。我只是认为在处理更复杂的操作时,需要更多的数学知识。 :) - rudnev
@rudnev: "你使用任何数学形式化符号"和"少一些数学"? 我不明白。有一个标准的正式方法。你不喜欢它。请更新问题,解释你想要什么是正式的,但又神奇地使用更少的数学。 - S.Lott
我已经阅读了这篇文章,我认为你是正确的,也许这是唯一可能的方法。可悲的是,如果是这样的话,我试图找到一些使用这种方法计划和实现的真实GUI示例。我知道如何使用集合理论进行数据库设计,它很有帮助。也许我会在当前项目中尝试制作一些复杂的状态图。 - rudnev
2个回答

1

使用消息传递作为抽象。优点:

  1. 复杂状态的困难在于复杂交互,这在并发系统(如典型GUI)中尤其棘手。通过消除共享状态,消息传递阻止了一个进程中状态的复杂性具有传染性。
  2. 消息传递并发具有良好的基础模型:例如Actor模型、CSP,两者都影响了Erlang。
  3. 它与函数式编程很好地集成:再次查看Erlang。Peter van Roy的书《计算机编程的概念、技术和模型》是一本优秀的文本,展示了编程语言的基本要素,如纯函数和消息传递,以及它们如何结合。该文本可作为免费PDF获取。

感谢您的晚回复。这本书非常出色。希望我能找到时间阅读。 - rudnev

0
它可能不是图灵完全的形式主义,但99%也很好:)
抱歉,但我宁愿提供NP完全解决方案:)
我的快速答案是测试驱动开发方法。但请继续阅读以获取更多信息。
在这种情况下,分解(不仅在 计算机科学 方面,而且在 数学 方面)非常有用。 您将复杂场景分解成许多较简单的场景,这些场景本身仍然可以很复杂,并且可以进一步分解。

通过这样的过程,您应该得到许多简单的函数(任务),它们大多数是相互独立的。

这非常重要,因为然后您可以单元测试这些简单的场景。

此外,更容易且更好的方法是遵循测试优先的方法,这允许在开发过程的最开始就看到分解。

您是否使用任何数学形式主义和方法来管理复杂对象的状态?

继续我所说的,对我来说最重要的是进行良好的分解,以便我可以确保质量并能够轻松地以自动化方式重现错误。


为了给您提供一个抽象的例子

您有一个复杂的场景A。每个场景都需要编写至少3个测试用例:正确输入、错误输入和边缘情况。

开始编写第一个测试用例(正确输入)时,我意识到测试变得太复杂了

因此,我将场景分解成更简单的A1A2A3。然后我再次为每个场景编写测试用例(最终应该至少有3*3=9个测试用例)。

我意识到A1仍然太复杂,所以我将其再次分解A1-1A1-2。现在我有4个不同的场景(A1-2、A1-2、A2、A3),并且有3*4=12个潜在的测试用例。我继续编写测试用例。

完成测试后,我开始实现,以便所有测试都能通过。之后,您有12个证明场景A(更准确地说是其部分)正常工作的证明。此外,您可能会为将所有分解部分组合在一起的场景A编写另外3个测试 - 这种测试通常(但并非总是!)可以视为集成测试。
然后假设在场景A中发现了一个错误。您不确定它属于哪个部分,但您怀疑它与A1-2或A3有关。因此,您为每个场景编写2个以上的测试来重现该错误(编写这样的测试,使其未达到您的期望而失败)。在重现错误后,您修复它并使所有测试都通过。
现在,您有了两个更多的证明,证明系统正确工作,并确保所有先前的功能以相同的方式工作。
在我看来,这种方法存在两个主要问题。
  1. 你需要编写许多测试用例并支持它们。许多开发人员只是不想这样做。
  2. 此外,分解过程更多的是艺术而非科学。好的分解将导致良好的结构、测试和可维护性,而糟糕的分解将导致很多痛苦和浪费时间。而且一开始很难判断分解是否好或坏

这个过程被称为测试驱动开发。我发现它是在科学和现实世界之间最接近的“开发流程规范化”。
因此,我在这里并没有真正谈论状态,而是行为和证明其正确性。
从个人经验来看,我应该提到ASP.NET WebForm技术上非常难以测试。为了克服这一点,我建议对ASP.NET WebForms应用MVP模式
与WebForms相反,ASP.NET MVC要容易得多。但仍然应该有一组所谓的“服务”(我们的场景),并单独(单元)测试它们,然后在接近集成测试环境的UI集成中进行测试。

对不起,但我不会为所有实际项目中的GUI编写测试。如果GUI比较复杂,那么测试将变得复杂两倍。这并不是形式主义,因为我仍然没有正式工具来验证我的步骤。 - rudnev
“我不会在实际项目中为所有GUI编写测试” - 我说过要编写单元测试,而不是GUI测试。 “测试将会复杂两倍” - 按照我所描述的分解复杂性。这不是形式主义,但您确实有工具来验证步骤:单元测试框架(nUnit、xUnit、MbUnit、Specs等 - 你来决定)。 - Dmytrii Nagirniak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接