是否可以使用非功能语言构建反应式应用程序?

时间:2013-12-23 21:01:23

标签: java functional-programming apache-camel reactive-programming

我想了解是否可以使用非功能性语言来实现反应性应用程序宣言背后的原则。

有人说,由于FP使用不可变状态和自由副作用函数,因此它们更容易实现并发,分布式和弹性系统。

但是我们怎样才能用Java来实现呢?

有些像Apache Camel这样的框架可以使用一些组件,比如 Camel RX Camel SEDA

这些框架是否足够?

我会尝试澄清我的问题:

我认为反应式编程是新的编程范式,而新的编程范式需要新的工具和框架。

功能语言以不同方式处理对象,这就是为什么有很多关于FRP使用基于事件和异步的事情的文章。

但是现在,支持Java或其他面向对象语言,让我们在Web应用程序中思考:

  1. 我们如何创建一个利用好的java Web应用程序 基于事件的前端。
  2. 然后,这些事件以平滑的方式异步传递信息到后端。
  3. 后端可以轻松扩展并具有弹性。
  4. 我知道可以创建一个使用java,servlet和EJB来完成这些需求的应用程序,但我的问题是,我们可以采用不同的方式吗? 更接近被动方法?

    我想到这样的事情:

    • 前端的一个不错的ajax框架,可以传递信息"随着后端顺利。
    • 在后端使用框架或库(Camel SEDA ou Camel RX)并行执行的方法。

    你认为这是一个好方法吗?

3 个答案:

答案 0 :(得分:5)

好吧,如果你看一下你引用的Reactive manifesto,你就会发现“functional”这个词根本没有出现。相反,有4个特定标准用于定义“被动”应用程序是什么:

  
      
  • 事件驱动
  •   
  • 可扩展
  •   
  • 弹性
  •   
  • 响应
  •   

Java中没有任何内容禁止您实现任何这些特征(除非极为罕见,极其高性能的情景“响应”)。并且 Java中的任何内容都禁止您编写受限于不可变对象和无副作用函数的代码(实际上,某些库,如Guava)鼓励您使用不可变对象以及具体化功能)。

像RxJava这样的框架可以进一步帮助您编写满足宣言中定义的标准的应用程序,方法是提供面向数据流的事件驱动系统,基本上是core tenet of reactive programming

答案 1 :(得分:4)

反应式编程并不新鲜,但对大多数人来说都是新手。它只是自1960年代以来一直存在的数据流的另一个名称。 Reactive Manifesto只是描述数据流和反应式编程的最佳品质的方法。

当然不需要功能语言,也不是一个庞大的图书馆。我已经实现了许多数据流系统。它们中的大多数都是辅助函数的集合,而不是大多数人称之为“库”的函数。这实际上取决于您在系统中需要哪种类型的功能。

数据流是一个非常“广泛”的主题。系统可以包含许多有用的功能,或者它可以具备基础知识。数据流的核心是数据控制执行。这与“contol-flow”(用于所有主流语言,如C#和Java)形成对比,您可以告诉计算机何时,何地以及如何处理数据。最常见的数据流形式是Pipeline模型......一系列盒子(或节点)通过链接(又称管道,电线或电弧)相继连接。

我刚刚开始检查可用于Java数据流编程的库,所以我现在不能给你一个具体的答案。似乎RxJava是Java中数据流的当前“名牌”,所以我会从那里开始。在我即将出版的书(http://DataflowBook.com)中,我将用通用语言(包括Java)将整个部分用于可用的数据流库。

答案 2 :(得分:2)

定义反应是第一步。例如:

  

反应程序中的每个状态定义了如何计算它,而运行时管理它们的评估,而不是发出命令来修改共享状态。运行时传播派生状态。如果您编写了电子表格公式,那么您已经完成了反应式编程。

     

ReactiveSax源于SAX的一个根本缺陷,使其与反应式编程模型不兼容。 SAX的思想非常适用于反应式编程,因为它是一个推送模型 - 事件被推送到管道中的下一个东西,它做了一些处理并将东西推送到下一个东西,等等。不幸的是,XMLReader接口定义了一个解析方法,调用解析链直到到达实际的解析器;该方法采用InputSource参数,该参数必须提供InputStream。其中存在缺陷 - 一个InputStream是一个阻塞I / O,它基本上是一个阻塞拉动。这违反了SAX的推送模型,使其不适合使用Future或Task进行反应式编程。如果一堆解析器阻塞所有等待输入的线程,并且它们提取输入的能力依赖于程序的其他位推送数据(进入,比如说,java.nio.Pipe或java.io.PipedWriter)那么你手上就会陷入僵局。

     

可观察的XmlReader允许您订阅它并将为您迭代Xml文档,在读取每个节点时通知您。使用它的程序员可以轻松地编写反应式LINQ表达式,以便在Xml中的特定节点上进行选择,从而产生与LINQ to XML非常相似但具有XmlReader的所有性能优势的代码。

     

Nu游戏引擎当然有资格作为功能性反应性的'在那 -

     

1)它是被动的,因为它使用用户定义的事件来获得连续的模拟状态。

     

2)它的功能是在任何地方都使用纯函数,即使在事件系统中也是如此。

     

但是,我无法将其描述为典型的一阶或更高阶的FRP系统,因为它既不使用随时间显式参数化的连续函数也不使用离散函数。相反,它使用经典迭代方法来推进游戏状态,类似于命令式的基于刻度的风格,但使用纯函数实现。

就现有API而言,一些适合该法案(事件驱动,可扩展,弹性,响应)的将是:

  • 另一个RDF分析器(ARP)

      

    RDF的流解析器。它使用推送模型,该模型由解析器控制应用程序的流程,以及应用程序对解析事件做出反应。对于非常大的文件,ARP不使用任何额外的内存,除非ExtendedHandler.discardNodesWithNodeID返回false或使用AResource.setUserData方法。在这些情况下,ARP需要记住文件生命周期内rdf:nodeID的使用情况。

  • 事件传递网络(EDN)

      

    然而,作为一名经验丰富的开发人员,您会知道随着时间的推移,简单的事情会逐渐增长并变得更加复杂。因此,我们不是编写一些不可改变的东西,而是建立灵活性,模块化和可扩展性。这里重要的是这个BPEL流程没有"知识"如何处理有效和无效的消息,因为它不需要知道。实际上,可以发布任何组件未订阅的事件。这些事件将在运行时被丢弃(在早期开发期间特别有用)。我们只需添加一个新的BPEL流程,该流程订阅ValidPerson和InvalidPerson事件,以便在不修改任何组成部分的情况下为我们的Composite引入其他功能,并且我们进一步确保完全解耦/模块化设计方法仍然有效。

  • Jini

      

    Jini是一种面向服务的体系结构,它定义了一种编程模型,该模型既利用和扩展了Java技术,又能够构建由服务和客户端联合组成的安全的分布式系统。 Jini技术可用于构建自适应网络系统,这些系统具有可扩展性,可扩展性和灵活性,这是动态计算环境中通常所需的。

  • XML管道语言(XPL)
      

    XML管道定义语言(XPL)是一种功能强大的声明性语言,用于使用管道隐喻处理XML。 XML文档进入管道,由XPL指令指定的一个或多个处理器有效处理,然后输出以进行进一步处理,显示或存储。 XPL具有高级功能,例如文档聚合,条件(" if"条件),循环,模式验证和子流水线。

Event Delivery Network(EDN)

Scaling JVM vs Node.js

<强>参考