热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

响应式编程_函数式响应式编程FRP简介

本文由编程笔记#小编为大家整理,主要介绍了函数式响应式编程-FRP简介相关的知识,希望对你有一定的参考价值。 函数式响应式编程,简称FRP,也叫函数式反应型编程,也可
本文由编程笔记#小编为大家整理,主要介绍了函数式响应式编程-FRP简介相关的知识,希望对你有一定的参考价值。


 函数式响应式编程,简称FRP,也叫函数式反应型编程,也可以称函数式反应式编程,总之一些中国特有的文字游戏,只需记住FRP即可。 F,即functional,函数;R,即reactive,反应、响应;P,即programming,编程之意。


    FRP最近几年在技术领域很火,但是它到底是什么,你为什么需要关注它,它背后的原理是什么,估计很少人能说清楚,那么现在,我们一起一探究竟。


    反应式(响应式)编程


    首先,我们先看一下反应式(响应式)编程,注意,不是函数式编程,也不是函数式反应型编程,这是三个不同的概念。


    我们先从一个简单的例子着手:一个开关和一个灯泡,开关控制灯泡,在编码期间,这两个组件被关联起来,一般来说,我们很少仔细去想怎么关联这两个组件,现在我们来仔细想下这个问题。


    一种处理方式我们称之为主动方式(proactive),是通过开关来改变灯泡的状态,此时,开关是主动的,灯泡是被动的,灯泡只是简单的接收开关的指令。


    如下图 

    

    代码描述如下:


       public class Switch {

            LightBulb lightBulb;

            void onFlip ( boolean enabled) {

                lightBulb.power(enabled);

            }

       }

    这里,开关类里包含了一个灯泡的实例,灯泡的状态总是能够随着开关的指令而改变。


    另外一种处理方法我们称之为响应方式(reactive),是灯泡监听开关的状态,随着开关状态的改变,而采取自己的行动,这里,灯泡就是响应式的了

函数式响应式编程-FRP简介(一)

    代码描述如下(以下的代码是观察者模式的实现方式,真正的响应式编程并不是这样的):


    public interface LightBulbIF {
       public void power(boolean bol);
    }


    public class LightBulb implements LightBulbIF {
       public void power(boolean bol) {
           System.out.println("I am ON ? " + bol);
       }
    }

    public static LightBulb create (Switch theSwitch) {

        LightBulbIF lightBulb = new LightBulb();

        theSwitch.addOnFlipListener(enabled -> lightBulb.power(enabled));

        return lightBulb;

    }


    Switch代码可如下编写:


    public class Switch {
       List listeners = new ArrayList();
       public void notify() {
           for (LightBulbIF listener : listeners) {
               listener.power(true);
           }
       }
   
       public LightBulbIF addOnFlipListener(LightBulbIF lightBulb) {
           listeners.add(lightBulb);
           return lightBulb;
       }
    }


    public static void main(String[] args) {
       Switch sw = new Switch();
       LightBulbIF lightBulb1 = T01.create(sw);
       LightBulbIF lightBulb2 = T01.create(sw);
       LightBulbIF lightBulb3 = T01.create(sw);
       sw.notify(); 
    }


    在这个响应式的编码方式里,灯泡观察开关发出的事件,从而改变自己的状态。


    对于终端用户来说,无论是主动方式还是响应方式,达到的效果是一样的,那么他们到底有什么不同呢?

    

    第一个不同是: 谁控制灯泡的亮灭,主动方式里,灯泡(LightBulb)必须由它的外部组件即开关(Switch)调用它的power方法来控制自己的亮灭,而响应方式里,自己控制自己的亮灭。


    第二个不同是:谁决定开关控制什么,主动方式里,开关自己决定它控制什么(蓝灯泡、绿灯泡,全由开关控制),而响应方式里,它只负责注册自己的监听者。

    

    尽管你可以根据不同的场景,选择主动方式或者响应方式编程,但是主动方式编程里,Switch直接控制LightBulb,耦合度很高,而响应式则不同,类之间不互相直接控制,而是借助listener关联其他类,这是一种松耦合的编码方式。


    在上面那个响应式的例子里,也存在一些问题:


    首先,监听者不通用,就是说Switch.OnFlipListener这个添加监听者的方法只适合Switch这个类,每个被监听的对象都需要实现自己的注册监听者的方法。


    其次,监听者直接进入被监听者内部,LightBulb必须在Switch类中,才能监听到Switch的变化,这样又会导致紧耦合,与我们的目标相去甚远,如下面的代码,监听者类型必须是LightBulbIF,这是重点,真正的响应式编程,就是要完全解耦:

    public class Switch {
       List listeners = new ArrayList();

       public void notify() {
           for (LightBulbIF listener : listeners) {
               listener.power(true);
           }
       }

    看看上面这段代码,你会发现:


    1. 状态的变化(即事件)会按照listener注册的顺序即刻通知给各个listener,而listener则直接执行自己的操作,设想这样一个场景,用户在搜索输入框内输入关键词,一般情况下每次输入框的内容变化都会产生一个事件,触发一个搜索操作,如果用户输入了一个错字,并且在一秒之内修改了一下,那么就会触发三次搜索操作:第一次按错误的关键字搜索,第二次按照删除了错字的关键字搜索,第三次按照正确的关键字搜索。如果这是一个同时在线人数很多的平台,这样的操作会给系统带来毫无意义的负担,而真正的响应式编程会通过scheduling events(后续探讨)来避免这种情况。


    2. 你无法保证在notify的时候,所有的listener都已经注册了。也就是说,注册listener的代码与触发事件的代码是分开的,复杂环境下,两者的顺序靠代码书写是无法保证的,而真正的响应式编程具有事务性,可以避免发生这种情况。


    还有listener实现线程安全的情况,忘记注销listener的情况等等,这些问题都可以通过FRP编程解决,后续篇章我们一起学习。


    首先我们知道了FRP要解决的问题,以后再学习FRP相关的概念时,就能够更又针对性的理解,敬请扫码关注盲点技术号,我们将持续努力与您一起学习探讨开发技术




推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
author-avatar
手机用户2502913137
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有