←←←←←←←←←←←← 快!点关注

在一个范式和技术堆栈一直在变化的世界中,保持竞争力和提高生产力和质量的斗争有时候证明是一项挑战。

在本文中,我想首先展示一下函数编程(FP)的优势,特别是加强Java编码体验。在尝试将范式转换为函数式编程时,我将尝试迭代我发现最重要的几个原因。请记住,这绝不是一个巨大的创新,我相信FP自70年代以来一直存在,但仅在最近几年它才获得吸引力并增加了人们的兴趣。我们来看看为什么!

并发

随着多核/多线程处理器的出现,函数式编程开始受到更多关注。这绝不是一个简单的巧合,因为函数式编程鼓励使用不可变对象,属性和变量应该是一种其值不能更改的数据容器)。看看下面代码:

private int aNumber;

public void setNumber(int numberParameter){

this.aNumber = numberParameter;

}

很简单吧?你以前可能已经看过很多次了。但是如果两个线程同时访问setNumber方法会发生什么?你可以想象某种阻塞可能会发生,最后,只有访问该方法的最后一个线程才会对aNumber的值有最终决定权。但这不确定,取决于各种因素,因此,我们可以说方法setNumber不是引用透明的(后面会详细介绍)。这种情况下不变性有助于推理代码,因为我们确信无论有多少线程访问它的一部分,它的值总是相同的。

引用透明和可测试性

函数式编程鼓励使用引用透明的函数。那是什么意思?嗯,这意味着一个函数总是可以被它的值替换,一切都将保持不变。看一下以下代码块:

import java.util.Random;

public class RandomValueProvider {

public int getSomeRandomValue(){

Random rand = new Random();

return rand.nextInt(50);

}

}

getSomeRandomValue()方法引用透明吗?试着用它的值替换它,它总是保持不变吗?可能不会。尽可能尝试使用引用透明的函数可能是一个好习惯。想象一下,测试上面的getSomeRandomValue方法比测试以下方法要困难得多:

public int getSum(int a,int b){

return a + b;

}

具有暗示名称的小函数通常比式样表示它们返回值的表达式更好。好处是能确保我们编写的(至少大部分)函数是确定性的。这将增加代码推理的简易性以及可测试性。

函数组合

在应用FP原则时,操作现在更简单,更具确定性,这一事实使我们能够通过将不同的功能组合在一起来创建更复杂的行为。将其他函数作为参数或返回函数一起接收的函数称为高阶函数。

这里的一些示例来自Java 8 Stream API。自2014年成为JDK的一部分(甚至在此之前)以来,已经在流上编写了大量内容。我只是想在这里使用Consumer函数接口展示一个简单的例子:

public void processListOfNumbers(List listOfNumbers, Consumer processor) {

return listOfNumbers.stream()

.forEach(number -> processor.accept(number));

}

客户端代码:

List numbers = Arrays.asList(5, 6, 7, 8);

Consumer numberPrinter = n -> System.out.println(n);

processListOfNumbers(numbers, numberPrinter);

方法processListOfNumbers是函数组合的一个示例,您可能会听到它有时被命名为高阶函数。在Java中,函数(也包括suppliers, consumers)是对象。这意味着我们可以应用它们,组合它们并将它们作为参数传递。

以FP风格编写的应用程序更加强大

在以函数式编写代码时,应用程序本身的更不容易出错。这是因为当您的移动一些组件时,应用程序往往变得更容易预测,更容易推理并且更能适应逆境。函数组合和不变性的一般用法将确保所有那些因为应用程序不同部分的状态变化而导致的错误现在默认消失了。该应用程序将更加强大,可以提供更短的开发 - >测试 - >调试迭代循环。

专注于“什么”而不是“如何”

假设我们有一个getUserById方法(在同一个类中)负责从数据库中获取相应的User对象,请使用以下Java流的经典应用程序:

public List getAdultUsers(List listOfUserIds) {

return listOfUserIds.stream().map(this::getUserById)

.filter(user -> user.getAge() >= 18)

.collect(Collectors.toList());

}

现在让我们看看非函数风格的相同代码:

public List getAdultUsers(List listOfUserIds) {

List adultUsers = new ArrayList<>();

for(int id: listOfUserIds) {

User user = getUserById(id);

if (user.getAge() >= 18) {

adultUsers.add(user);

}

}

return adultUsers;

}

除了第二段略长外,我们还可以注意到这段代码需要花时间来“解释”此操作的每个步骤是如何完成的:创建一个空白列表,迭代id,获取每个用户,添加一些基于条件表达式的用户到空白列表,完成并返回收集的用户。

另一方面,在第一段中,功能方法更侧重于“什么”。代码在做什么?它将一些ID映射到某些用户,将其过滤掉并将其余用户收集到列表中。有人可能会争辩说,通过在第二种情况下提取小方法可以实现同样的目的,但我相信第一段的流和函数作为数据方法仍然更好。它将我们的函数置于业务逻辑的最前沿,具有与在我们的应用程序中移动的任何其他数据相同的状态。

更好看的方法签名

当我们的功能从命令式转变为函数式时,命名也一目了然,以下方法很难通过其签名来阅读:

public void executeProcess() {

// executing some mysterious stuff!

}

代码做了什么?为什么它不想要我们的任何输入参数,为什么它不想返回任何结果?你能测试一下吗?你能读懂吗?不容易吧。如果像下面这样看起来如何?

public ExecutionStatus executeProcess(Process processToBeExecuted) {

// execute "processToBeExecuted" and return some status

}

只需采用一些FP概念,并在这个简单的情况下使用它们,代码就变得更具可读性。函数现在是可通过查看它的方法签名来说明自己(虽然方法名称可能仍然可以改进)。它需要一个Process输入并以某种ExecutionStatus状态返回。除了直接在代码中提供更好的“文档”之外,签名变得更有意义。执行什么Process?我们可以查看Process对象并在运行时查看它。它发挥作用后会发生什么?我然后可在我们的流程中使用该函数的返回结果。

结论

如今,无论我们是在处理遗留代码还是新建绿地项目,我们都可以使用一些东西来提高日常工作的质量和生产率。函数编程从不同的角度进行编码。它通常意味着更简洁,但如果给予适当的照顾,也会提高可读性。它还帮助我们解决一些常见的痛苦,例如并发编程中的竞争条件,令人讨厌的对象状态错误或难以遵循的代码。

写在最后:

秃顶程序员的不易,看到这里,点了关注吧!

点关注,不迷路,持续更新!!!

java秃顶_【本人秃顶程序员】在Java中使用函数范式提高代码质量相关推荐

  1. java的套娃汇总(黑马程序员基础java总结)

    java里面存在很多套娃关系,这里对于基础的套娃做一个小小的总结 对象调用 对象调用顾名思义就是new一个新的对象出来,在主程序中调用 设想一个场景,我要定义一个手机对象,里面有牌子,价格,和一些其他 ...

  2. Java基础学习总结(148)——如何提高代码质量

    前言 人跟人的能力千差万别,所以写出来的代码质量,肯定是不同的.有的人,写一个小逻辑,可能需要100行,而有的人,可能仅仅需要10行.代码永远会有Bug,在这方面没有最好只有更好.模块化与面向对象是实 ...

  3. 【MCTalk Live】网易对话谷歌:如何成为一个顶50个的A+++++程序员

    MCTalk Live首秀 ---------- 从"互联网时代"到"移动互联网",互联网给时代带来全新的产业生产模式以及理念,而当下,我们站在"人工 ...

  4. java跟python对比_【多年的Java程序员总结Java与Python的对比 】

    多年的Java程序员总结Java与Python的对比 作为一个有多年职场经验的技术员,每当我遇到同行时,我都会问一句"你现在用的是什么语言?你喜欢用哪种语言?"至于答案,容后再说. ...

  5. 黑马程序员全套Java教程_Java基础教程_异常(含扩展)(二十三)

    黑马程序员全套Java教程_Java基础教程_异常(含扩展)(二十三) 1.1 异常概述与异常体系结构 1.2 JVM遇到异常时的默认处理方案 1.3 异常处理 1.4 异常处理之try--catch ...

  6. java多语言编程语言_为什么很多程序员信仰“Java是世界上最好的编程语言”

    看到这个标题,估计有不少PHPer要跳进来打我膝盖,跪请各位Java程序员保我周全. 因为PHP是所有web开发中使用最多的语言,也被称为最有生命力的语言,所以也就自然而言有了"PHP是世界 ...

  7. java c++ python哪个好_程序员学java好还是python语言好 c++又如何

    技术程序员学Java.C++.Python... 分析对比,到底学什么语言吃香,哪种语言最靠谱,如何学好这些语言呢? 几天前,我们在知识上看到这样一个问题:"java,C++,Python, ...

  8. html类名定义规则_好程序员分享Java语言中的标识符规则

    好程序员分享Java语言中的标识符规则,在编程过程中,经常需要在程序中定义一些符号来标记一些名称,如包名.类名.方法名.参数名.变量名等,这些符号被称为标识符.标识符可以由任意顺序的大小写字母.数字. ...

  9. java程序员的名言_收集53个程序员励志名言

    1.要么做第一个,要么做最好的一个. 2.信念和目标,必须永远洋溢在程序员内心. 3.最累的时候,家人是你最好的归宿. 4.C程序员永远不会灭亡.他们只是cast成了void. 5.真正的程序员认为自 ...

最新文章

  1. 中国开发者新福利:大模型API接口出炉,让普通用户玩转内容生成
  2. 微课丨华为的18条军规
  3. ExtJs4–表格--Grid
  4. php返回图片给安卓_android上传图片到PHP的过程详解
  5. Java设计模式之适配器模式在jdk中的应用
  6. linux 不同ip 相同mac arp,linux – nmap和arp-scan不一致的IP-MAC结果
  7. 扩展坞可以把手机投到显示器吗_解锁4K 60Hz毕亚兹USB Type-C扩展坞体验
  8. iphone备忘录自带的扫描功能扫完文件后如何保存为图片
  9. java初学者练手项目_最适合初学者的Java练手项目!
  10. 科密考勤机对比和参考价
  11. 计算机讲Word文档中的组合,电脑Word文档中两个表格如何合并
  12. Shape Shifter——制作简单动画
  13. 投影技术的分类与应用
  14. 初中英语语法(004)-代词
  15. 03.C 语言实现3.5寸虚拟软盘
  16. 深扒ASML 的玩法,对工控企业生态圈的思考
  17. SAP CO TCode
  18. OPPOReno4SE和华为畅享20 哪款好
  19. 王牌战士没显示我的服务器,王牌战士号没了怎么回事 游戏档案被销号解决方法...
  20. Spring框架——IOC、DI

热门文章

  1. 杉德支付php代码实现_[转]PHP语言开发Paypal支付demo的具体实现
  2. 【踩坑日记】Vue组件@click事件点击没有反应
  3. MAR位数反应存储单元的个数 MDR位数=存储字长
  4. 什么是SDK,它是怎样威胁我们的隐私?
  5. 清点代码库 (25 分)
  6. 树莓派访问 群晖 里的共享文件夹
  7. 录屏储存失败因为5823_屏幕录制存储失败因为5823
  8. 短租民宿多平台房态同步管理系统
  9. 如何让自己打计算机打字快起来,电脑快速打字的技巧
  10. 租用gpu训练神经网络(矩池云)