程序员 rs编码_为什么声明性编码使您成为更好的程序员
程序员 rs编码
在许多情况下,具有功能组成的声明式解决方案提供了优于传统命令式代码的出色代码指标。 阅读本文并了解如何使用具有功能组成的声明性代码成为一名更好的程序员。
在本文中,我们将仔细研究三个问题示例,并研究用于解决这些问题的两种不同技术(命令式和声明式)。
本文中的所有源代码都是开源的,可以在以下位置获得
https://github.com/minborg/imperative-vs-declarative 。 最后,我们还将看到如何将本文的知识应用于数据库应用程序领域。 我们将使用Speedment Stream作为ORM工具,因为它提供了与数据库中的表,视图和联接相对应的标准Java Streams,并支持声明性构造。
从字面上看,有无数个示例候选可用于代码度量评估。
问题范例
在本文中,我选择了开发人员在工作期间可能会遇到的三个常见问题:
SumArray
遍历数组并执行计算
分组
并行汇总值
休息
通过分页实现REST接口
解决技术
正如本文开头所暗示的,我们将使用以下两种编码技术来解决上述问题:
势在必行
一种命令式解决方案,其中我们使用带有for循环和显式可变状态的传统代码样式。
陈述式
声明性解决方案,其中我们组合了各种功能以形成解决该问题的高阶复合功能,通常使用
java.util.stream.Stream
或其变体。
代码指标
然后,我们的想法是使用适用于SonarQube(此处为SonarQube社区版,版本7.7)的不同解决方案的静态代码分析,以便我们可以为问题/解决方案组合得出有用的标准化代码量度。 然后将这些指标进行比较。
在本文中,我们将使用以下代码指标:
LOC
“ LOC”表示“代码行”,是代码中非空行的数量。
陈述
是代码中语句的总数。 每条代码行上可能有零到很多语句。
圈复杂度
指示代码的复杂性,是对通过程序源代码的线性独立路径数量的定量度量。 例如,单个“ if”子句在代码中提供了两条单独的路径。
了这里的维基百科。
认知复杂性
SonarCube声称:“认知复杂性不同于使用数学模型评估软件可维护性的实践。 它从Cyclomatic Complexity设定的先例开始,但是使用人工判断来评估应如何计算结构并决定应向模型整体添加哪些内容。 结果,它得出的方法复杂性得分比以前的模型更能使程序员感到可维护性相对更公平。 这里 SonarCube自己的页面上。
通常,最好构想一个解决方案,其中这些指标较小,而不是较大。
作为记录,应该注意的是,以下设计的任何解决方案只是解决任何给定问题的一种方法。 如果您知道更好的解决方案,请随时告诉我,随时通过https://github.com/minborg/imperative-vs-declarative提交拉取请求。
遍历数组
我们从一个简单的开始。 该问题示例的对象是计算int数组中元素的总和,并将结果返回为
long
。 以下接口定义了问题:
public interface SumArray { long sum( int [] arr); }
当务之急
以下解决方案使用命令式技术实现SumArray
问题:
public class SumArrayImperative implements SumArray { @Override public long sum( int [] arr) { long sum = 0 ; for ( int i : arr) { sum += i; } return sum; } }
声明式解决方案
这是使用声明性技术实现SumArray
的解决方案:
public class SumArrayDeclarative implements SumArray { @Override public long sum( int [] arr) { return IntStream.of(arr) .mapToLong(i -> i) .sum(); } }
请注意, IntStream::sum
仅返回一个int,因此我们必须应用中间操作mapToLong()
。
分析
SonarQube提供以下分析:
下表显示了SumArray
的代码指标(通常越低越好):
技术 | LOC | 陈述 | 圈复杂度 | 认知复杂性 |
---|---|---|---|---|
势在必行 | 12 | 5 | 2 | 1个 |
功能性 | 11 | 2 | 2 | 0 |
这是它在图形中的外观(通常越低越好):
并行汇总值
该问题示例的对象是将“ Person
对象分组到不同的存储桶中,其中每个存储桶构成一个人的出生年份和一个工作的国家/地区的唯一组合。对于每个组,应计算平均工资。 聚合应使用公共的ForkJoin池并行计算。
(不变的) Person
类是这样的:
势在必行
我们还定义了另一个称为YearCountry
不变类,该类将用作分组键:
势在必行
定义了这两个类之后,我们现在可以通过以下接口定义此问题示例:
势在必行
当务之急
实现对GroupingBy
示例问题的命令性解决方案并GroupingBy
。 这是解决问题的一种解决方案:
势在必行
声明式解决方案
这是一个使用声明性构造实现GroupingBy
的解决方案:
势在必行
在上面的代码中,我使用了一些静态导入
Collectors
类(例如Collectors::groupingBy
)。 这不会影响代码指标。
分析
SonarQube提供以下分析:
下表显示了GroupingBy
的代码指标(越低越好):
技术 | LOC | 陈述 | 圈复杂度 | 认知复杂性 |
---|---|---|---|---|
势在必行 | 52 | 27 | 11 | 4 |
功能性 | 17 | 1个 | 1个 | 0 |
相应的图形如下所示(通常越低越好):
实施REST接口
在这个示例性问题中,我们将为Person对象提供分页服务。 出现在页面上的人员必须满足某些(任意)条件,并且必须按照给定的顺序进行排序。 该页面应作为不可修改的Person对象列表返回。
这是捕获问题的接口:
势在必行
页面的大小在一个单独的实用程序类RestUtil
:
势在必行
当务之急
这是Rest接口的命令性实现:
势在必行
声明式解决方案
下列类以声明的方式实现Rest接口:
势在必行
分析
SonarQube提供以下分析:
下表显示了Rest的代码指标(通常越低越好):
技术 | LOC | 陈述 | 圈复杂度 | 认知复杂性 |
---|---|---|---|---|
势在必行 | 27 | 10 | 4 | 4 |
功能性 | 21 | 1个 | 1个 | 0 |
在这里,相同的数字显示在图表中(再次降低通常会更好):
Java 11的改进
上面的示例是用Java 8编写的。使用Java 11,我们可以使用LVTI(局部变量类型推断)来缩短声明性代码。 这会使我们的代码短一些,但不会影响代码指标。
势在必行
与Java 8相比,Java 11包含一些新的收集器。 例如,
Collectors.toUnmodifiableList()
可以使我们的声明式Rest解决方案更短:
势在必行
同样,这不会影响代码指标。
摘要
对我们的三个示例性问题的代码度量取平均会得到以下结果(通常越低越好):
考虑到本文的输入要求,当我们从命令式构造到声明式构造时,所有代码度量都有显着改进。
在数据库应用程序中使用声明性构造
为了从数据库应用程序中获得声明式构造的好处,我们使用了Speedment Stream 。 Speedment Stream是基于Stream的Java ORM工具,可以将任何数据库表/视图/联接转换为Java流,从而使您可以在数据库应用程序中运用声明性技能。
您的数据库应用程序代码将变得更好。 实际上,针对数据库的具有Speedment和Spring Boot的分页REST解决方案可能表示为:
势在必行
Speedment提供了Manager<Person> persons
,并构成数据库表“ Person”的句柄,并且可以通过Spring @AutoWired
进行管理。
结论
选择声明式而不是命令式解决方案可以大大降低通用代码的复杂性,并可以提供许多好处,包括更快的编码,更好的代码质量,更高的可读性,更少的测试,减少的维护成本等等。
为了从数据库应用程序中的声明性构造中受益,Speedment Stream是一种可以直接从数据库提供标准Java Streams的工具。
如今,对于任何当代的Java开发人员来说,必须掌握声明性构造和功能组成。
资源资源
文章源代码: https : //github.com/minborg/imperative-vs-declarative
SonarQube: https ://www.sonarqube.org/ Speedment Stream: https ://speedment.com/stream/ Speedment初始化程序: https ://www.speedment.com/initializer/
翻译自: https://www.javacodegeeks.com/2019/08/declarative-coding-makes-better-programmer.html
程序员 rs编码
程序员 rs编码_为什么声明性编码使您成为更好的程序员相关推荐
- 为什么声明性编码使您成为更好的程序员
在许多情况下,具有功能组成的声明式解决方案提供了优于传统命令式代码的优越代码度量. 阅读本文并了解如何使用具有功能组成的声明性代码成为更好的程序员. 在本文中,我们将仔细研究三个问题示例,并研究用于解 ...
- 什么是伪代码,它如何使你成为更好的程序员?
努力学习编程?通过学习伪代码来掌握代码.但是什么是伪代码,它真的有帮助吗? 当你第一次开始学习编程时,在构建第一个应用程序之前,需要学习很多东西.像程序员一样思考可以帮助你将问题分解为算法来解决问题. ...
- python2默认编码_解决Python2.x编码之殇
Python编码问题一直困扰了我许久,之前有过一些总结,但并不系统,比较凌乱.当然python2.x编码问题本身,便是剪不断理还乱.本篇将系统介绍python2.x编程中会遇到的一些编码问题,并给出解 ...
- 北大青鸟消防设备类型编码_探测器该如何编码?即报警区域、探测区域的真正用途...
<火灾自动报警系统设计规范> GB 50116-2013中说到 报警区域是将火灾自动报警系统的警戒范围按防火分区或楼层等划分的单元. 报警区域应根据防火分区或楼层划分:可将一个防火分区或一 ...
- 免费制作微信小程序开发关于旅游_教大家怎么一步步免费自己做微信小程序
小程序很火,很好的流量入口,但是没有编程基础的很难写出小程序,找网络公司做又太贵,今天就教大家怎么自己去制作一个属于自己的小程序! 想制作小程序需要准备的清单如下: 1.微信公众平台(mp.weixi ...
- access 此程序未正确安装_圣空法师:把你大脑中错误的程序消除、卸载,安装上正确的程序...
圣空法师开示: 大家都不明白,烦恼和菩提是同时的,在菩提启用的当下,如果你不会用,它就变成烦恼了. 我们来到这里,既然为了解决烦恼的问题,你就不要没解决烦恼,还增加了很多烦恼.你看我们才几个人?凡是有 ...
- python程序员推荐笔记本_震惊脸!这5个软件难道只有Python程序员才知道吗?
后台回复'0816',加入Python技术交流群~ 双11过去了,大家买了些什么好东西呀? 因为上一个电脑被我拆坏了,于是这次我在小明的帮助下,买了一台新电脑. 拿到电脑的第一件事,就是安装各种软件. ...
- 电子白板 矢量 编码_当涉及白板编码采访时,请记住准备
电子白板 矢量 编码 by Andy Tiffany 通过安迪·蒂芙尼(Andy Tiffany) 当涉及白板编码采访时,请记住准备 (When it comes to whiteboard codi ...
- 信息论与编码_哈夫曼编码
哈夫曼树 哈夫曼树(Huffman Tree)也是一种特殊的二叉树,这种树的所有叶子结点都带有权值,从中构造出带权路径长度最短的二叉树,即哈夫曼树. 哈夫曼树的定义 设二叉树具有n个带权值的叶子结 ...
最新文章
- android-技术教程-调试程序的基础,在控制台上打印出想打印的东西 转载
- HLG1159 MAGI System【大整数乘法】
- 《CCNP TSHOOT 300-135认证考试指南》——5.10节定义关键术语
- 图像分类、检测,语义分割等方法梳理
- 目前流行的装修风格_当下最流行十种装修风格,总有一款适合你!
- c语言图形界代码,求个用最简单的的代码来实现图形界面…
- 数据挖掘学习指南!!
- ubuntu实现简单的划词工具
- 随心测试_软测基础_004职责与质量
- 网易有道词典--关闭自动发音
- ​七周二次课(5月7日)监控io性能、free命令、ps命令、查看网络状态、linux下抓包...
- 【转】android开发必看资源URL
- python批量查询IP物理地址输出到Exel
- app live photo_live photo动态壁纸下载-Live Photo动态壁纸app下载 苹果版v2.1-PC6苹果网...
- TalkingData Ad Tracking开启反作弊模式
- 我的七年之痒与二人世界
- Julia:Plots 包的属性汇总
- fastadmin btn-ajax,FastAdmin 在线命令生成时出错的分析
- Django 项目管理
- 【Effective C++】总结