有没有数学方法来管理复杂对象的状态?

发布于 2024-08-24 21:35:42 字数 440 浏览 1 评论 0原文

我通常使用 ASP.net Web 表单作为 GUI,这可能是最“有状态”的技术之一。但它适用于任何具有状态的技术。有时表单很棘手且复杂,有超过 30 个元素并且超过 3 个元素。每个元素的 3 种状态。设计这种表单的直观方法通常可以达到 90% 的效果。其他 10% 通常会找到测试人员或最终用户:)。

在我看来,问题是我们应该在同一个对象上想象很多场景,这比独立操作的结果要困难得多。

从函数式编程课程中,我知道最好的方法是不要使用状态管理,而使用纯函数和按值传递变量以及所有这些东西,这是非常形式化的。有时,我们无法避免。

您是否使用任何数学形式和方法来管理复杂对象的状态?与 Haskell 中的 monad 不同,但它可以用于更传统的业务应用程序和语言 - Java、C#、C++。

这可能不是图灵完备的形式主义,但 99% 也很棒:)。

抱歉,如果这只是另一个风滚草问题:)

I usually use ASP.net web forms for GUI, maybe one of most "stateful" technologies. But it applies to any technology which has states. Sometimes forms are tricky and complex, with >30 elements and > 3 states of each element. Intuitive way of designing such a form usually works for 90%. Other 10% usually find testers or end-users:).

The problem as i see it that we should imagine a lot of scenarios on the same object, which is much harder than a consequence of independent operations.

From functional programming courses I know that best way is not to use state management and use pure functions and variable passing by value and all these stuff, which is greatly formalized. Sometimes, we cannot avoid it.

Do you use any math formalisms and approaches to state management of complex objects? Not like monads in Haskell, but which can be used in more traditional business applications and languages - Java, C#, C++.

It may be not Turing-complete formalism, but 99% will be great also:).

Sorry if it is just another tumbleweed question:)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苍景流年 2024-08-31 21:35:42

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

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

Use message-passing as an abstraction. Advantages:

  1. The difficulty with complex state is complex interactions, which are especially hairy in concurrent systems like typical GUIs. Message-passing, by eliminating shared state, stops the complexity of state in one process from being infectious.
  2. Message-passing concurrency has nice foundational models: e.g., the Actor model, CSP, both of which influenced Erlang.
  3. It integrates well with functional programming: check out Erlang again. Peter van Roy's book *Concepts, Techniques, and Models of Computer Programming is an excellent text that shows the fundamental ingredients of programming languages, such as pure functions, and message-passing, and how they can be combined. The text is avilable as a free PDF.
昔梦 2024-08-31 21:35:42

这可能不是图灵完备的形式主义,但 99% 也很棒:)。

抱歉,但我宁愿提供 NP 完整的解决方案:)

我的快速回答是 Test-驱动方法。但请进一步阅读以了解更多信息。

我认为我们应该解决的问题
在同一个场景上想象很多场景
物体,比物体坚硬得多
独立运营的结果。

在这种情况下,分解(不仅在计算机科学 意义,但在数学中也是非常有用的。
您将复杂场景分解为许多简单场景,而这些场景本身仍然很复杂,并且可以进一步分解。

作为这样一个过程的结果,您最终应该得到许多简单的功能(任务),这些功能(任务)大多彼此独立。
这非常重要,因为这样您就可以单元测试这些简单的场景。
此外,遵循测试优先方法会更容易、更好,它允许查看在开发过程的一开始就进行分解。

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

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


给您一个抽象示例

您有一个复杂场景A。您始终需要为每个场景编写至少 3 个测试:正确输入、错误输入和极端情况。

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

因此,我将场景分解 A 为不太复杂的 A1A2A3。然后我再次开始为每个测试编写测试(我应该最终得到至少 3*3=9 个测试)。

我意识到 A1 仍然太复杂而无法测试,因此我再次将其分解A1-1,<代码>A1-2。现在我有 4 个不同的场景(A1-2、A1-2、A2、A3)和 3*4=12 个潜在测试。我继续编写测试。

我做完之后。我开始实施,所以我的所有测试都通过了。之后,您有 12 个证明场景 A(更准确地说是其部分)正确工作。此外,您可以为场景 A 编写另外 3 个测试,将其所有分解的部分结合起来 - 这种测试经常(但并非总是如此!)可以被视为集成测试

然后我们假设在场景 A 中发现了一个错误。您不确定它属于哪一部分,但您怀疑它与 A1-2A3 有关。因此,您为每个场景再编写 2 个测试重现错误(编写这样一个测试,但无法满足您的期望)。重现错误后,修复它并使所有测试通过。

现在,您还有 2 个正确工作系统的证明,可确保之前的所有功能都以相同的方式工作。

在我看来,这种方法有两个主要问题。

  1. 您需要编写大量测试并支持它们。许多开发人员只是不想这样做。
  2. 此外,分解的过程更多的是艺术而不是科学。良好的分解将带来良好的结构、测试和可支持性,而糟糕的分解将导致大量的痛苦和浪费时间。而且一开始很难判断分解是好是坏

这个过程称为测试驱动开发。我发现它是最接近的开发过程“形式化”,在科学与现实世界之间发挥着良好的作用

因此,我在这里并不是真正谈论状态,而是谈论行为并证明其正常工作。

从个人经验来看,我应该提到 ASP.NET WebForm 在技术上非常难以测试。
为了克服这个问题,我建议为 ASP.NET WebForms 应用 MVP 模式

与 WebForms 相比,ASP.NET MVC 更容易测试
但是,您仍然应该拥有一组所谓的“服务”(我们的场景)和(单元)单独测试它们,然后在接近集成测试的环境中测试 UI 集成。

It may be not Turing-complete formalism, but 99% will be great also:).

Sorry, but I'd rather provide NP-complete solution :)

Quick answer from me would be Test-Driven Approach. But read further for more.

The problem as i see it that we should
imagine a lot of scenarios on the same
object, which is much harder than a
consequence of independent operations.

In such cases the decomposition (not only in computer science sense, but in mathematical too) is very useful.
You decompose complex scenario in many simpler ones, which in turn can still be complex by themselves and can be decomposed further.

As a result of such a process you should end up with a number of simple functions (tasks) mostly independent of each ones.
This is very important because then you can UNIT TEST those simple scenarios.
Additionally, it is much easier and better to follow test-first approach which allows to see the decomposition in the very beginning of the development process.

Do you use any math formalisms and approaches to state management of complex objects?

To continue what I said, for me the most important thing is to make a good decomposition so that I can ensure the quality and being able to easily reproduce errors in an automated manner.


To give you an abstract example:

You have a complex scenario A. You always need to write at least 3 tests for each scenario: correct input, incorrect input and corner case(s).

Starting to write first test (correct input) I realize that the test becomes too complex.

As a result, I decompose scenario A into less complex A1, A2, A3. Then I start writing tests for each of them again (I should end up with at least 3*3=9 tests).

I realise that A1 is still too complex to test, so I decompose it again into A1-1, A1-2. Now I have 4 different scenarios (A1-2, A1-2, A2, A3) and 3*4=12 potential tests. I continue writing the tests.

After I am done. I start implementation, so all my tests pass. After that you have 12 proves that scenario A (more precisely its parts) works correctly. Additionally, you might write another 3 tests for the scenario A that combines all of its decomposed parts - this kind of testing is often (but not always!) can be seen as Integration testing.

Then let's assume a bug is found in scenario A. You are not sure which part it belongs to, but you suspect that it is related to A1-2 or A3. So you write 2 more tests for each of the scenario to reproduce the bug (write such a test that fails not meeting your expectations). After you have reproduced the bug you fix it and make ALL tests pass.

Now you have 2 more proves of correctly working system that ensures all the previous functionality is working the same way.

There are 2 main major problems with this approach IMO.

  1. You need to write a lot of tests and support them. Many developers just do not want to do that.
  2. Additionally, the process of decomposition is more art than science. Good decomposition will result in a good structure, tests and supportability while a bad one will result in a lot of pain and wasted time. And it is hard to tell if the decomposition is good or bad at first.

This process is called Test-Driven-Development. I find it to be the closest "formalization" of development process that plays nice between science and real world.

So I do not really talk about state here but rather behavior and proving it works correctly.

From personal experience, I should mention that ASP.NET WebForm is technically VERY hard to test.
To overcome that, I would suggest to apply MVP pattern for ASP.NET WebForms.

As opposed to WebForms, ASP.NET MVC is so much easier to test.
But still, you should have set of so called "services" (our scenarios) and (unit) test them separately, then test the UI integration in the environment close to Integration tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文