客户端多线程编程解决思路

今天这篇文章主要介绍函数式编程的思想。 

  • 什么是函数式编程?

  • 函数式编程有什么用?

什么是函数式编程?

面向对象:
数据和对数据的操作(函数)紧紧耦合
其他对象调用这些操作只需要通过接口,如果新操作就需要新接口
核心抽象模型是数据自己
核心活动是组合新对象和拓展已经存在的对象,这是通过加入新的方法实现的

函数编程:
数据与函数是松耦合的
调用函数以及将函数组合起来表达
核心抽象模型是函数,不是数据结构
核心活动是编写新的函数 

函数编程就是把函数做成一个管道。可以直接拼接管道形成新的管道(函数的组合)。简单来说,函数式编程是一种强调以函数使用为主的软件开发风格。 (不明白的话,可以最后再回来看这个对比)

下面我们通过例子来简单的演示一下函数式编程的魅力。
现在的需求就是输出在网页上输出 “Hello World”。
可能初学者会这么写。 

document.querySelector('#msg').innerHTML = '<h1>Hello World</h1>'  

这个程序很简单,但是所有代码都是死的,不能重用,如果想改变消息的格式、内容等就需要重写整个表达式,所以可能有经验的前端开发者会这么写。 

function printMessage(elementId, format, message) { 
    document.querySelector(elementId).innerHTML = `<${format}>${message}</${format}>` 
} 
printMessage('msg', 'h1', 'Hello World')  

这样确实有所改进,但是任然不是一段可重用的代码,如果是要将文本写入文件,不是非 HTML,或者我想重复的显示 Hello World。
那么作为一个函数式开发者会怎么写这段代码呢? 

const printMessage = compose(addToDom('msg', h1, echo)) 
printMessage('Hello World')

解释一下这段代码,其中的 h1 和 echo 都是函数,addToDom 很明显也能看出它是函数,那么我们为什么要写成这样呢?看起来多了很多函数一样。 

其实我们是将程序分解为一些更可重用、更可靠且更易于理解的部分,然后再将他们组合起来,形成一个更易推理的程序整体,这是我们前面谈到的基本原则。 

可以看到我们是将一个任务拆分成多个最小颗粒的函数,然后通过组合的方式来完成我们的任务,这跟我们组件化的思想很类似,将整个页面拆分成若干个组件,然后拼装起来完成我们的整个页面。 

我们现在再改变一下需求,现在我们需要将文本重复三遍,打印到控制台。 

var printMessaage = compose(console.log, repeat(3), echo)   
printMessage(‘Hello World’)

可以看到我们更改了需求并没有去修改内部逻辑,只是重组了一下函数而已。

纯函数和不可变性

纯函数指没有副作用的函数,相同的输入有相同的输出。
不可变性指入参是不可以被任何地方修改的。 

var counter = increment() { return ++counter; }

这个函数就是不纯的,它读取了外部的变量,可能会觉得这段代码没有什么问题,但是我们要知道这种依赖外部变量来进行的计算,计算结果很难预测,你也有可能在其他地方修改了 counter 的值,导致你 increment 出来的值不是你预期的。 

对于纯函数有以下性质:
  • 仅取决于提供的输入,而不依赖于任何在函数求值或调用间隔时可能变化的隐藏状态和外部状态。

  • 不会造成超出作用域的变化,例如修改全局变量或引用传递的参数。 但是在我们平时的开发中,有一些副作用是难以避免的,我们可以通过将其从主逻辑中分离出来,使他们易于管理。 

函数式编程有什么用?

函数即不依赖外部的状态也不修改外部的状态,函数调用的结果不依赖调用的时间和空间状态,做到无状态(不保存状态,每次都是一样的)。相对于 OOP 而言,FP 的思想则是摒弃外部状态,只依赖函数内的变量,可以说是粒度更小的面向对象---函数级别的。这使得单元测试和调试都更容易。每一个纯函数都是线程安全,更容易被并行执行。 

在 FP 风格下,我们习惯将复杂逻辑切割成一个个小模块,通过组合这些模块实现新的业务功能,当有新的需求到来时,我们尽可能地复用已有模块达到目标。函数的输出仅依赖函数参数,不受任何外部环境影响。这样的函数可测试性强,也非常容易进行组合。 

在具体业务中我们通常还需要权衡组件的复用性和开发体验,如果组件被拆分的过于细,固然复用性会提升,但文件数量会增加,对应的文档和沟通成本也会增加,这也是 FP 在实践过程中经常遭人诟病的点,即复用性提升后带来的额外开发成本。 

我们在实践的时候,可以先尝试着去让我们的业务逻辑实现纯函数和不可变性。这样我们的代码至少可以在多线程的情况下,可以尽可能的减少问题。

数据驱动

一旦我们做到了函数式编程,你就会发现整个程序的驱动都是数据来完成的。从起点的入参开始驱动了整个链条。这样就可以让程序自然而然的做到了数据驱动。数据是可以跨进程、跨平台、跨时间的。用数据(状态)来描述上游逻辑,这样就可以实现逻辑可记录、可回放。


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容