并不是说Reactive 一定要搭配Functional,只是搭配起来更好用,而後面介绍到的Reactor & WebFlux,基本上也都是Functional Programming,所以在这边先介绍一下到底何谓Functional Programming。
函式语言程序设计(英语:functional programming)或称函式程序设计、泛函编程,是一种编程范式,它将电脑运算视为函式运算,并且避免使用程序状态以及易变物件。其中,λ演算为该语言最重要的基础。而且,λ演算的函式可以接受函式作为输入参数和输出返回值。
上述源自於wiki,简单的说Functional Programming就是前一天介绍的Programming paradigm其中宣告式的一种,所以她其实就是一种抽象的概念,尽量透过函式来编写程序码,会有以下几个特性。
值可以指定给变数,也可以当作参数传入方法(函数)中,则称为一级值(first-class value
)。Java当中int、long、String或是物件等等都可以指定给变数并传入方法(函数),这些也就是first-class value,而能够指定给变数以及当作参数的函式,则被称为First-class citizen
(一等公民), Java 8 之後,提供了Functions
、Suppliers
、Consumers
、Predicates
等等Functional Interfaces,Java 才终於有了First-class citizen。
java 有了First-class citizen之後,随之而来就是higher-order function
,当一个函式(function)传入一个或多个函式做为参数,他就是higher-order function,举例来说,在操作Stream的时候常用到的map()
、filter()
、flatMap()
.......等都是higher-order function,他们都是将函式做为参数。
@Override
public Stream<R> filter(Predicate<? super R> predicate) {
return new StreamDecorator<R>( delegate.filter( predicate ), closeHandler );
}
@Override
public <R1> Stream<R1> map(Function<? super R, ? extends R1> mapper) {
return new StreamDecorator<>( delegate.map( mapper ), closeHandler );
}
@Override
public IntStream mapToInt(ToIntFunction<? super R> mapper) {
return new IntStreamDecorator(
delegate.mapToInt( mapper ),
closeHandler
);
}
同样的input,一定会输出相同的output。
大部分的说明都是没有副作用,避免状态或是资料改变,但现实中的企业应用专案,需要去log或是存入db资料,很难去做到完全的no side effects,所以追求最少的副作用是一个折衷的办法。
不可更改,也就是当物件的状态在创建後就不可以更动。
若遵守以上几个条件,当需要多处理并发(Concurrency
)与多执行绪(Parallelism
)的时候,程序相对就可以单纯许多,毕竟不会改变也就不用去synchronized
,而在维运的时候也不会到处去找BUG是否是因为某个状态不如预期,可想而知这就是Functional Programming的优点之一。下面是一个简单的将偶数乘上5并加总的范例。
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = data
.stream()
.filter(i -> i % 2 == 0)
.map(i -> i * 5)
.reduce(0, Integer::sum);
System.out.println(sum);
//150
Java 本来的语言特性是更友善物件导向设计(OOP), OOP的特色就是万般皆物件,用物件的概念去对应并设计程序,比较好入门而且更具体一点不像是Functional 这麽抽象,另外OOP的重点在於资料(DATA
),FP则关注於操作(operations
),所以有人说若是资料多操作少建议使用OOP,资料少操作多则推荐使用FP。我个人的观点认为在JAVA中很难完全舍弃掉OOP,所以在OOP中去使用一些FP的写法或许是一个不错的办法。
>>: JavaScript学习日记 : Day5 - 基本型别(三)
在 Day03 我们使用 GCE 建立一台 VM,今天要学习如何连线到虚拟机,并在服务器上使用 No...
在 Scrum Guide 中其实并没有明确地提到所谓的「精链会议」( Refinement) ,因...
树有非常多变型,下面是Wiki的截图 以下简单介绍几种常听到的~ AVL Trees、Red Bla...
前言 Python是一种易於学习且功能强大的程序语言,可以呼叫使用相当完整的标准资料库,我们也称之为...
来到这系列的最後一篇,除了心得结语外,也讨论的学习 PixiJS 的过程 时期1:不考虑效能,这时期...