状态机 复杂逻辑问题

by Oguz Gelal

由Oguz Gelal

状态管理中的逻辑 (The Logic in State Management)

The standardization of transactional state management brought predictability to front-end development. Then with immutability and single-source-of-truth for state, applications became more maintainable and robust. However, there is still some ambiguity surrounding what to do with the business logic.

事务状态管理的标准化为前端开发带来了可预测性。 然后,由于具有不变性和状态的真实来源,应用程序变得更易于维护和增强。 但是,围绕如何处理业务逻辑仍然存在一些歧义。

I propose a model where the business logic gets operated under the same command channel that the reducers use. Managing logic with the same unidirectional transactions brings many benefits during development. I will first walk through the problem in more detail. Then, I will explain how this model works over Reclare, the library that implements this model. Finally I will discuss some of these benefits.

我提出了一个模型,其中业务逻辑在与reducers使用的相同命令通道下进行操作 。 使用相同的单向事务管理逻辑在开发过程中会带来很多好处。 我将首先更详细地解决该问题。 然后,我将解释该模型如何在实现该模型的库Reclare上工作。 最后,我将讨论其中的一些好处。

与数据的永恒斗争 (Eternal struggle with data)

In the early days, people used to build user interfaces with plain HTML and CSS. They handled DOM (document object model) manipulations using JavaScript or jQuery. It was reasonable back then — front-end applications were simple and not as data-driven. But then the responsibility grew into fetching and handling data, instead of only displaying it. DOM manipulation lost its feasibility.

在早期,人们曾经使用纯HTML和CSS构建用户界面。 他们使用JavaScript或jQuery处理DOM(文档对象模型)操纵。 那时是合理的-前端应用程序很简单,而不是数据驱动的。 但是后来责任变成了获取和处理数据,而不仅仅是显示数据。 DOM操作失去了可行性。

Front-end frameworks solved this problem by having DOM reflect the underlying state of the application. Developers no longer had to worry about updating the DOM, but managing the state was still on their plate.

前端框架通过让DOM反映应用程序的基础状态来解决此问题 。 开发人员不再需要担心更新DOM,但是仍然可以管理状态。

Then modern state management started to gain some ground. Elm and Flux standardized event-sourcing-style transactional state management in front-end development. How and when the state can update got restricted with unidirectional data flows. This brought predictability to the state, made it easier to follow and reason with.

然后,现代国家管理开始取得进展。 Elm和Flux在前端开发中标准化了事件源样式的事务状态管理。 状态的更新方式和时间受到单向数据流的限制。 这给状态带来了可预测性,使跟踪和推理变得更加容易。

Redux made a breakthrough with immutability and single-source-of-truth for state. It also introduced flexible, pure, functional and composable reducers. These brought some advantages over the Flux architecture, but there is still some ambiguity about how to handle business logic and where it should live. There are many articles and discussions on this topic, but no clear answer seems to exist.

Redux在不变性和状态单一来源方面取得了突破。 它还引入了灵活,纯净,功能强大且可组合的减速器。 与Flux架构相比,这些带来了一些优势 ,但是在如何处理业务逻辑以及将逻辑放置在何处仍存在一些歧义 。 关于此主题的文章和讨论很多,但是似乎没有明确的答案。

This got me confused as much as it confused others. I decided to address this problem and find a clean way to handle business logic in my applications. Then I came up with the idea of bundling business logic together with reducers. This allowed logic to operate together with reducers under the same event channel.

这让我很困惑,也让其他人感到困惑。 我决定解决此问题,并找到一种干净的方法来处理我的应用程序中的业务逻辑。 然后,我想到了将业务逻辑与化简器捆绑在一起的想法。 这使得逻辑可以与减速器在同一事件通道下一起运行。

I realized that this approach brought more than just some organizational benefits. It brought other advantages like predictability and declarativeness in logic. There was a need for a library to orchestrate logic together with the state and maintain all the benefits of modern state management. This is when I decided to create Reclare.

我意识到这种方法不仅带来了一些组织上的好处。 它带来了其他优势,例如逻辑的可预测性和声明性。 需要一个图书馆与国家协调逻辑并保持现代国家管理的所有利益。 这是我决定创建Reclare的时候 。

声明简介 (Brief Introduction to Reclare)

Reclare is a simple library that revolves around declarations and events. A declaration is a simple object invokable by Reclare. It describes the situational condition for it to invoke, and what to do if its invocation takes place. It’s reaction could be updating the state, executing logic / side-effects, or both. Here is what a declaration looks like:

Reclare是一个简单的库,围绕声明事件 。 声明是Reclare可以调用的简单对象。 它描述调用它的情况条件 ,以及调用它时该怎么办 。 它的React可能是更新状态,执行逻辑/副作用,或两者兼而有之。 声明如下所示:

View an example on JSFiddle

查看有关JSFiddle的示例

It is a general purpose API and there are different kinds of declarations. Different kinds gets invoked in different ways. Currently there are two kinds: event and subscription declarations.

这是一个通用的API,并且有不同种类的声明。 不同种类的调用方式不同。 当前有两种:事件和订阅声明。

Event declarations listen to the event channel and subscribe to specific events. The broadcast method could be used to broadcast events to the event channel. The first parameter is the event key, followed by the event payload. This payload gets passed on to the declaration functions.

事件声明侦听事件通道并订阅特定事件。 broadcast方法可用于将事件广播到事件频道。 第一个参数是事件密钥,后跟事件有效负载。 该有效负载传递给声明函数。

broadcast("event_key", { bar: 'foo' })

Subscription declarations get invoked upon every state change. Depending on the declaration type, the functions may receive extra parameters, but the structure does not change.

每次状态更改时都会调用订阅声明 。 根据声明类型,函数可能会接收额外的参数,但结构不会改变。

When Reclare context gets created, all declarations get merged by their on keys. This reduces the complexity of finding declarations on broadcasts to O(1) time. It also makes working with declarations very natural, as it is possible to have multiple declarations with the same event key. Here is an example:

创建Reclare上下文时,所有声明都将通过其on键合并。 这降低了查找广播到O(1)时间的声明的复杂性。 这也使得使用声明非常自然,因为可以使用相同的事件键进行多个声明。 这是一个例子:

声明生命周期 (Declaration Lifecycle)

The declaration lifecycle begins when one or more declarations get triggered. First, all situation functions of all declarations that have the broadcasted event on their on key get evaluated. If the situational condition holds, reducers and reactions of that declaration get queued. Then, the queued reducers start getting executed.

当一个或多个声明被触发时,声明生命周期开始。 首先,有广播对他们的活动的所有声明的所有功能情况on评估关键搞定。 如果情况保持不变,则该声明的归约者和React会排队。 然后,排队的减速器开始执行。

Each one receives the state and returns a new state, which is then piped on to the next one. Each reducer triggers the subscription declarations. They receive the state before and after the reducer that triggered them. Next, the queued reactions get executed. Each reaction receives the initial and the current state as arguments. They get executed after the reducers, so the state they receive is at its final. The event payload gets passed on to every function executed on each step.

每个人都接收该状态并返回一个新状态,然后将其通过管道传递到下一个状态。 每个reducer都会触发订阅声明。 他们收到触发它们的减速器之前和之后的状态。 接下来,执行排队的React。 每个React都将初始状态和当前状态作为参数。 它们在减速器之后执行,因此它们收到的状态处于最终状态。 事件有效负载将传递到在每个步骤上执行的每个函数。

好处 (Benefits)

Modern state management libraries focus only on managing the application state. The logic behind the scenes is usually overlooked. There are benefits in operating the state and business logic together. Granted there needs to be a separation between the two. The impurities and side effects of logic should be kept away from the management of the state. But they functionally belong to each other, so they should coexist and be operated together.

现代状态管理库仅专注于管理应用程序状态。 通常会忽略幕后的逻辑。 一起操作状态和业务逻辑有很多好处 。 当然,两者之间需要分开。 逻辑的杂质和副作用应远离状态管理。 但是它们在功能上是彼此属于的,因此它们应该共存并一起操作。

可预测的逻辑 (Predictable logic)

Managing business logic with the same unidirectional transactions with reducers brings a similar predictability to logic that it does to the state. It makes it easier to reason with, follow, understand and test the code.

使用减少器以相同的单向事务来管理业务逻辑,将为状态带来类似的逻辑可预测性。 它使推理,遵循,理解和测试代码变得更加容易。

Predictability in the context of business logic is not a one-to-one comparison to the predictability of the state, but the underlying idea is the same. Broadcasted events can be recorded with their payloads and the invocations they caused. Thus, it is possible to travel back in the event history to tell what happened in the course of execution. You could investigate which declarations got invoked, which reactions they executed, and how they changed the state.

业务逻辑上下文中的可预测性与状态的可预测性不是一一对应的,但是基本思想是相同的。 广播的事件可以记录其有效载荷及其引起的调用。 因此,有可能返回事件历史记录以告诉执行过程中发生了什么。 您可以调查调用了哪些声明,它们执行了哪些React以及它们如何更改状态。

代码结构和碎片 (Code Structure and Fragmentation)

A typical front-end codebase contains many different types of entities. For instance, a typical React + Redux + redux-saga codebase would have containers, components, actions, reducers, types, selectors, sagas, services and others depending on the selection of libraries. Dan Abramov mentions in his article You might not need Redux:

典型的前端代码库包含许多不同类型的实体。 例如,根据库的选择,典型的React + Redux + redux-saga代码库将具有容器,组件,动作,缩减器,类型,选择器,sagas,服务等。 Dan Abramov在他的文章中提到您可能不需要Redux :

People often choose Redux before they need it. “What if our app doesn’t scale without it?” Later, developers frown at the indirection Redux introduced to their code. “Why do I have to touch three files to get a simple feature working?” Why indeed!

人们经常在需要之前选择Redux。 “如果没有它,我们的应用程序无法扩展怎么办?” 后来,开发人员对引入其代码的间接Redux感到不满意。 “为什么我必须触摸三个文件才能使一个简单的功能正常工作?” 为何如此!

You shouldn’t have to touch three different files to work on a single function. Codes that have functional relevancy should not get fragmented into different entities. They should be grouped and handled together instead.

您不必触摸三个不同的文件即可使用一个功能。 具有功能相关性的代码不应分为不同的实体 。 应该将它们分组并一起处理。

Reclare attempts to make this ordeal more pleasant with declarations and duck files.

声明尝试通过声明鸭子文件使这个折磨更愉快。

Declarations are bundles that hold reducers together with reactions. Since they execute upon the same event, they will be functionally relevant.

声明是将还原剂与React结合在一起的束。 由于它们在同一事件上执行,因此它们在功能上是相关的。

The duck files’ approach is based on the ducks modular redux by Erik Rasmussen. It is a proposal to bundle shattered pieces of Redux together as an isolated module.

Duck文件的方法基于Erik Rasmussen 编写的Ducks模块化redux 。 建议将粉碎的Redux碎片捆绑在一起,作为一个隔离的模块。

Reclare follows this pattern in its own way. It allows bundling declarations and other relevant entities together into a single file. Moreover, it supports composition, allowing you to have logical parent-child relationships. Duck files can export other entities like constants and selectors. It is a simple yet handy way to divide your code into modules.

声明以其自己的方式遵循此模式。 它允许将声明和其他相关实体一起捆绑到一个文件中。 此外,它支持合成,使您具有逻辑上的父子关系。 鸭子文件可以导出其他实体,例如常量和选择器。 这是将代码分为模块的简单而便捷的方法。

模块化和声明性 (Modularity and Declarativeness)

Reclare operates both reducers and reactions together with uni-directional transactions. This allows you to build your logic in a declarative and modular nature. I will explain with a simple login scenario:

Reclare既可以运行reducer,也可以进行React以及单向事务。 这使您能够以声明性和模块化的方式构建逻辑。 我将用一个简单的登录方案来说明:

The login form component broadcasts login_submitted with email and password on submit. It also receives the loading status in the props, which gets handled by the request module below.

登录表单组件在提交时广播login_submitted以及电子邮件和密码。 它还在道具中接收加载状态,该状态由下面的请求模块处理。

Above is the module that manages the login process. The first declaration gets invoked on login_submitted if the input is valid. It broadcasts the on_request event with the request details. Notice how it doesn’t care at all about handling the requests? The module is only interested in the outcome of the requests of type login.

上面是管理登录过程的模块。 如果输入有效,则在login_submitted调用第一个声明。 它广播带有请求详细信息的on_request事件。 请注意,它根本不关心处理请求吗? 该模块仅对类型为login的请求的结果感兴趣。

The next two declarations listen to the request_success and request_fail events. Upon those events, if the request type condition holds, they will get invoked. The first one saves the user to the state and triggers a route change, and the second one shows an error message.

接下来的两个声明侦听request_successrequest_fail事件。 在这些事件上,如果请求类型条件成立,则将调用它们。 第一个将用户保存到状态并触发路由更改,第二个显示错误消息。

This is an example of a general purpose module which handles the requests and loading states. The first declaration gets invoked on on_request event. Once invoked, it will set the loading state for the request type, and then start the request. Then based on the outcome, it will broadcast request_success or request_fail events. It will also broadcast request_resolved, which terminates the loading state.

这是处理请求和加载状态的通用模块的示例。 在on_request事件上调用第一个声明。 调用后,它将设置请求类型的加载状态,然后启动请求。 然后,根据结果,它将广播request_successrequest_fail事件。 它还将广播request_resolved ,从而终止加载状态。

There are two take-aways from this example. The first is how the business logic is managed. Most state management libraries using unidirectional data flows will allow you to manage the state declaratively. But with Reclare, you can take advantage of this pattern to manage your business logic as well.

此示例有两个要点。 首先是如何管理业务逻辑。 大多数使用单向数据流的状态管理库将允许您以声明方式管理状态。 但是使用Reclare,您也可以利用此模式来管理业务逻辑。

Second is the modularity. Every declaration and module is an isolated piece of code that gets invoked by particular events. The declarations receive a payload and does their thing: performs a set of actions and / or updates the state. They are unaware and unaffected by other parts of the code.

第二是模块化。 每个声明和模块都是被特定事件调用的独立代码。 声明接收有效负载并执行其操作:执行一组操作和/或更新状态。 他们没有意识到,也不受代码其他部分的影响。

This will help you to keep the mental mapping of your code even when it scales. It also brings many advantages while testing your code.

这将帮助您即使在扩展代码时也可以保持思维导图。 在测试代​​码时,它还带来了许多优势。

最后的话 (Final Words)

Since I’ve completed the implementation and tests of Reclare, I’ve used it a few times on side projects and production environments at work. So far it’s been a fun experience, and I had nothing but success with it. I truly hope Reclare can be of help to the community as much as it has helped me.

自完成Reclare的实现和测试以来,我已经在工作中的辅助项目和生产环境中使用了几次。 到目前为止,这是一个有趣的经历,除了成功,我什么都没有。 我真的希望Reclare能够对社区有所帮助,就像对我的帮助一样。

One last thing: there is an official React middleware built on top of the new Context API. When I wrote this article, Reclare was ready for usage in a React project. It can also be used without the middleware on any JavaScript project. I will look into creating middlewares for other frameworks (unless someone else wants to do it ?).

最后一件事:在新的Context API之上构建了一个官方的React中间件 。 当我写这篇文章时,Reclare已准备好在React项目中使用。 也可以在没有JavaScript项目的中间件的情况下使用它。 我将研究为其他框架创建中间件( 除非其他人愿意这样做 ?)。

As for the future plans, here is a short-term roadmap:

至于未来的计划,这是一个短期路线图

  • Creating Reclare DevTools for debugging创建Reclare DevTools进行调试
  • I will also be looking into Redux DevTools integration我还将研究Redux DevTools集成
  • More documentation and examples更多文档和示例
  • Contribution guidelines贡献准则
  • TypeScript supportTypeScript支持
  • Tests and improvements on React-ReclareReact-Reclare的测试和改进
  • Ability to extend the declaration API扩展声明API的能力
  • reducerDefault/reactionDefault

    reducerDefault / reactionDefault

You can also find some examples on the repositories:Reclare — https://github.com/reclarejs/reclareReact-Reclare — https://github.com/reclarejs/react-reclare

您还可以在存储库中找到一些示例: Reclare — https://github.com/reclarejs/reclare React-Reclare — https://github.com/reclarejs/react-reclare

翻译自: https://www.freecodecamp.org/news/the-logic-in-state-management-2820d0353fed/

状态机 复杂逻辑问题

状态机 复杂逻辑问题_状态管理中的逻辑相关推荐

  1. PDM系统在技术状态管理中的应用研究

    摘要:PDM(产品数据管理)技术以及相应的应用软件是上世纪80年代出现的,以技术管理为依托,具有四大内容即技术状态标识.技术状态控制.技术状态纪实和技术状态审核,形成自动化的办公流程,随着国民经济的不 ...

  2. 商业逻辑12讲之管理沟通的逻辑

    1. 概述 本文是记录商业逻辑12讲之管理沟通的逻辑的一些笔记. 2. 管理就是沟通 沟通包括听说读写四个类型. 3. 管理沟通的五大要素 3.1 沟通者 3.2 沟通的对象 3.3 信息策略 3.4 ...

  3. 商业逻辑12讲之管理思维的逻辑

    1. 概述 本文是记录商业逻辑12讲之管理思维的逻辑的一些笔记. 2. 开篇语 为什么要学习管理思维? 提高我们的思维能力,特别是理论思维能力 避免思考为题的简单化.过于依赖个人经验 基本内容为企业管 ...

  4. promise的三种状态_一.Promise中核心逻辑的实现

    首先看一下Promise代码: let promise =new Promise((resolve,reject)=>{resolve('成功');//reject('失败'); }) prom ...

  5. mount 返回状态_状态管理模式 — Vuex如何使用?

    Extract 试想当我们在开发一个Vue应用程序时,如果在一个项目中频繁的使用组件传参的方式来同步data中的值,一旦项目结构变得复杂,管理和维护这些数据将变得十分繁琐,为此,Vue为这些被多个组件 ...

  6. 仓库货位卡标识牌_仓储管理中的货位与标识管理

    在现实的仓储管理中,我们常常听说有发错料.发串料的情况发生.究其原因,我认为这其中难免有保管人员粗心大意的主观成分,而最主要的.客观的因素应该是货位与标识不清.打个比方,我们指定了一个仓管员去某个货位 ...

  7. 逻辑回归 数据_数据科学中的逻辑回归

    逻辑回归 数据 逻辑回归 (Logistic Regression) Logistic regression is an applied mathematics analysis methodolog ...

  8. 报名软件批次分类code不能为空_批次管理中批次确定常见问题的分析方法

    批次管理中批次确定常见问题的分析方法 处理多年批次管理 (Batch management) 的相关问题,对批次管理中批次确定 (Batch determination) 这一小部分功能略有心得,所以 ...

  9. 逻辑对计算机,对计算机模拟中的逻辑、方法论的几点认识

    摘  要:本文通过机器发现研究中的启发式搜索法.机器学习研究中的归纳算法,以及Prolog系统的非单调性质,揭示计算机模拟技术在逻辑.方法论上的一些新特点. 关键词:启发式搜索;机器学习;Prolog ...

最新文章

  1. 27岁华裔小伙一战成名!搞出美国新冠最准预测模型
  2. 史上最全SpaceX火箭数据开源,核心、组员舱、起落架、发射信息全都有!
  3. 软件项目实施方案_进度、预算、人员和合同变更——科研项目管理精义与实操(十五)...
  4. 学习在.NET Core中使用RabbitMQ进行消息传递之持久化(二)
  5. java 联合_Java标记的联合/和类型
  6. 每天一点matlab——字符分割
  7. 谷歌插件 axure +去广告插件
  8. Linux 开发环境 -- glibc 升级(不建议轻易升级)
  9. MyEclipse 不提示jsp代码
  10. ModHOMM3 使用说明
  11. 电脑w ndows无法自动修复,电脑无法自动修复,开不了机怎么办
  12. Android 悬浮窗日志工具
  13. 企业终端无法获取到 IP地址
  14. 传统目标检测方法研究(一)
  15. MVP衣明志——15年技术生涯
  16. 流量矿石团队成员出席“区块链技术与金融领域创新应用培训会”
  17. 有关ros kinetic无法安装报错unmet dependencies及解决
  18. 动网论坛8.2经典注入漏洞利用
  19. 云存储哪家强:AWS、Azure、Google、SoftLayer
  20. Android 短信验证码自动填写

热门文章

  1. 输出一行星花 1110 java
  2. 创建一个django的项目 使用自创的虚拟环境
  3. requests-处理不信任的ssl证书
  4. dj电商-需求分析-购物车模块与订单模块
  5. django-登陆功能-使用ajax实现
  6. mysql float精度与范围总结
  7. 业务实时监控服务ARMS推出小程序监控支持各种小程序
  8. eclipse黑色主题
  9. 九、Citrix服务器虚拟化Xenserver虚拟机模版
  10. 从源码角度看Spark on yarn client cluster模式的本质区别