浅谈函数式编程
发布日期:2021-05-09 02:25:55 浏览次数:8 分类:博客文章

本文共 1836 字,大约阅读时间需要 6 分钟。

1. 前言

最近开始忙起来了,写东西的时间越来越少了。这几天开始在 Java 开发中尝试函数式编程风格。所以就写点小东西来分享一下。

2. 什么是函数式编程?

在我看来函数式编程就是把函数作为一等公民来使用就是函数式编程。平常我们开发都是在处理数据。面向对象中都在处理类。而函数式编程不是在写函数就是在写函数的路上。我们来看看 Java 中函数式编程的演进之路。我小时候玩过一种廉价的黑白屏游戏机,只能玩俄罗斯方块。这种是不可扩展的。

public void playGame(){         //  只能玩俄罗斯方块  }

这种机器给童年带来了不少的乐趣。后来小伙伴有了一台gameboy,这种掌机的好处在于它可以插卡。一张卡一个游戏,最有名的莫过于 《超级马里奥》 和《打砖块》了。这时候机器是完全可扩展的了。

public void  playGameboy(GameboyCard card){            card.getGame().run()      }

虽然可以扩展但是卡的价格非常贵,当时买卡的渠道还很少。那时候其实就想如果能自己造 gameboy 游戏就好了(然后我就来搞编程?)。理想中的游戏机是我们不关心你什么风格的游戏,只要你能放入符合接口的游戏卡中并且在我这个游戏机中跑就行。

所以我们定义了一个固定的游戏卡接口:

/** * @author Felordcn * @since 2019/10/31 22:13 */@FunctionalInterfacepublic interface Card {    Game  apply();}

只要符合这种接口的游戏卡都能插到机器中玩:

/**     * Fun.     *     * @param card the card     */    void fun(Card card) {        Game game = card.apply();        game.run();    }

熟练面向对象的同学们会说这不就是面向接口编程吗?是的你说的没有问题。但是这里 Card 接口只干一件事就是提供游戏。我们的重心是游戏卡吗?显然不是!有趣好玩的游戏才是我们的目的所在。于是我们不管他是卡还是光碟甚至网路,只要能提供游戏给我们娱乐都符合我们的需要。

// 玩插卡游戏机  fun(() -> new CardGame());   // 玩 PSP   fun(() -> new PSPGame());   // more

作为一名码农,平常我们都在写 SQL。无论大厂小厂,不管单体还是分布式。SQL 总能帮我们解决很多业务关系处理。SELECT、 INSERT、 UPDATE、 DELETE 每一种命令只要是 SQL 规范数据库,不管是什么表都会是一致的操作。你声明了什么命令就执行什么操作。这时数据与函数是松耦合的。正是这样的特点让我们实现了“万变不离其宗”。这也是一种另类的函数式编程。

3. 面向对象和函数式编程冲突吗?

面向对象一直处于我能操作什么数据、这种数据我该怎么操作的范式中。而函数式编程一直沉浸于给我操作数据的方法中。面向对象最大优点是多态性和封装;函数式编程优势是抽象化和声明式命令风格,两者其实是正交,可互补的,可在同一程序中共存。争论是面向对象好还是面向函数好跟争论哪门语言好一样都是非常极端的。对于面向对象来讲:存在的并不一定都是对象,函数就是对象;对于函数式编程来说:存在的并不总是纯粹的,副作用总是真实存在的。总之,面向对象侧重于分解,函数编程侧重于组合。

4. 函数式编程特点

函数风格的编程拥有自己的一些特点:

  • 函数作为一等公民。 可以作为参数传递、从函数里返回、可以赋值给变量。

  • 带有闭包的 Lambda 表达式和匿名函数,这是广泛的多态。

  • 不变性,大部分无态处理,在函数式程序中,变量是通过外部传入或者申明获得值的。变量不能被改变

  • 基于不可变进而可以无副作用的调用。

  • 通过 tail call 实现递归的性能优化。

  • 提供动态的、可组合的开发思路。

5. 总结

今天简单表达了我对函数式编程的一些理解,对于习惯了面向对象的 Java 开发者来说,理解函数式编程并不容易。它不仅仅有 Lambda 和匿名函数!更多的是一种思想。这里推荐一个很好的 Java 函数式编程库 vavr 。有兴趣的同学可以学习下。

  

转载地址:https://www.cnblogs.com/felordcn/p/12142521.html 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【震精】LinkedList源码竟然可以这样玩!!
下一篇:Spring Boot 2 实战:自定义启动运行逻辑

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月18日 06时22分21秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

【大话Mysql面试】-MYSQL的两种存储引擎MyISAM与InnoDB的区别是什么? 2021-06-29
【大话Mysql面试】-InnoDB可重复读隔离级别下如何避免幻读?MVCC和next-key是什么 2021-06-29
【大话Mysql面试】-Mysql如何恢复数据?如何进行主从复制?Binlog日志到底是什么? 2021-06-29
理解String.intern()和String类常量池疑难解析例子 2019-04-26
python flask打造前后端分离的口罩检测 2019-04-26
【大话Mysql面试】-MySQL基础知识 2019-04-26
【大话Mysql面试】-MySQL数据类型有哪些 2019-04-26
【大话Mysql面试】-MySQL数据引擎 2019-04-26
【大话Mysql面试】-常见SQL语句书写 2019-04-26
【大话Mysql面试】-SQL语句优化 2019-04-26
【大话Mysql面试】-Mysql事务以及隔离级别 2019-04-26
【大话Mysql面试】-Mysql索引 2019-04-26
【大话Mysql面试】-Mysql锁 2019-04-26
【大话Mysql面试】-Mysql常见面试题目 2019-04-26
08 【多线程高并发】Java线程间通信的方式 2019-04-26
【数据结构与算法】什么是跳表?通俗易懂来理解跳表 2019-04-26
【数据结构与算法】什么是图?图是什么?快速带你回顾图有关的知识点 2019-04-26
【数据结构与算法】什么是串?什么是KMP算法?字符串匹配是什么? 2019-04-26
【数据结构与算法】什么是布隆过滤器?如何防止缓存穿透的问题? 2019-04-26
【Java锁体系】CopyOnWriteArrayList是什么?线程安全的arraylist是哪个? 2019-04-26