使用Java为何总写出C风格的代码?

news2025/1/16 16:00:41

“你看你所有代码都是把字段取出来计算,然后,再塞回去。各种不同层面的业务计算混在一起,将来有一点调整,所有代码都得跟着变。”

在实际的开发过程中,有不少人都这么写代码的。Java写的代码应该有Java的风格,而这种却处处体现着C风格。

1 编程范式(Programming paradigm)

程序的编写模式。使用什么编程范式,通常意味着主要使用的代码结构。设计角度,编程范式决定你在设计时,可使用的元素有哪些。主流的编程范式:

1.1 结构化编程(structured programming)

通过一些结构化的控制结构进行程序的构建。最熟悉控制结构是if/else这样的选择结构和do/while这样的循环结构。

结构化编程是最早普及的编程范式,现在最典型的结构化编程语言是C语言。C语言控制结构的影响极其深远,成为了很多程序设计语言的基础。

1.2 面向对象编程(object-oriented programming)

最主流编程范式,核心概念是对象。写出的程序本质就是一堆对象之间的交互。给我们提供了一种管理程序复杂性的方式,最重要的就是多态(polymorphism)。

1.3 函数式编程(functional programming)

近些年重新崛起的编程范式。核心概念是函数。它的函数来自于数学里面的函数,所以,和我们常规理解的函数有个极大不同:不变性。即一个符号一旦创建就不再改变。

函数式编程的代表性语言LISP,还没哪门函数式编程语言能够完全独霸一方。

编程范式不仅仅是提供了一个个的概念,更重要的是,它对程序员的能力施加了约束:

  • 结构化编程,限制使用goto语句,它是对程序控制权的直接转移施加了约束
  • 面向对象编程,限制使用函数指针,它是对程序控制权的间接转移施加了约束
  • 函数式编程,限制使用赋值语句,它是对程序中的赋值施加了约束。

与其说这些编程范式是告诉你如何编写程序,倒不如说它们告诉你不要怎样做。

2 多范式编程

编程范式与具体语言的关系不大,就好比你的思考与用什么语言表达是无关的。但实际每种语言都有自己的主流编程范式。
如C语言主要是结构化编程,而 Java主要是面向对象编程。但丝毫不妨碍程序员们在学习多种编程范式之后,打破“次元壁”,将不同编程范式中的优秀元素吸纳进来。这里的重点是“优秀”,而非“所有”。

比如在Linux设计中,有个虚拟文件系统(Virtual File System,简称 VFS)的概念,你可以把它理解成一个文件系统的接口。在所有的接口中,其中最主要的是file_operations,它就对应着我们熟悉的各种文件操作。

下面是这个结构的定义,这个结构很长,我从中截取了一些我们最熟悉的操作:

struct file_operations {
  loff_t (*llseek) (struct file *, loff_t, int);
  ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
  ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
  int (*open) (struct inode *, struct file *);
  int (*flush) (struct file *, fl_owner_t id);
  int (*release) (struct inode *, struct file *);
  ...
}

如果你要开发一个自己的文件系统,只需要把支持的接口对应着实现一遍,也就是给这个结构体的字段赋值。

换个角度看,这个结构体主要的字段都是函数指针,文件系统展现的行为与这些函数的赋值息息相关。只要给这个结构体的字段赋值成不同参数,也就是把不同的函数关联上,这个文件系统就有了不同的行为。
熟悉面向对象编程,这不就是多态?

C是一门典型的结构化编程语言,而VFS的设计展现出来的却是面向对象编程的特点,编程范式的“次元壁”在这里被打破。

类似的设计还有很多,比如,Java里有一个著名的基础库,Google出的Guava。它里面就提供了函数式编程的基础设施。在Java 8之前,Java在语法上并不支持函数式编程,但这并不妨碍我们通过类模拟函数。
C++有一个functor概念,也就是函数对象,通过重载 () 这个运算符,让对象模拟函数的行为。

无论是在以结构化编程为主的语言中引入面向对象编程,还是在面向对象为主的语言中引入函数式编程,在一个程序中应用多种编程范式已经成为趋势。

越来越多的程序设计语言开始将不同编程范式的内容融合起来。Java从Java 8开始引入了Lambda语法,写出函数式编程代码。

多范式编程会越来越多,是因为关注点是做出好的设计,写出易维护代码,所以,我们会尝试着把不同编程风格中优秀的元素放在一起。比如,我们采用面向对象来组织程序,而在每个类具体的接口设计上,采用函数式编程的风格,在具体的实现中使用结构化编程提供的控制结构。

开头之所以批评,关键点就是没有把各种编程范式中优秀的元素放到一起。Java是提供对面向对象的支持,面向对象的强项在于程序的组织,它归功的设计元素应该是对象,程序应该是靠对象的组合来完成,而把它写成平铺直叙的结构化代码,这不值得鼓励。

学习不同的编程范式,将不同编程范式中的优秀元素应用在我们日常的软件设计之中,已经由原来的可选项变成了现在的必选项。否则,你即便拥有强大的现代化武器,也只能用作古代的冷兵器。

3 总结

编程范式指的是程序的编写模式。编程范式对程序员的能力施加了约束,理解编程范式的一个关键点在于,哪些事情不要做。

编程范式与具体语言的关系不大,但很多语言都有着自己主流的编程范式。但现在的一个趋势是,打破编程范式的“次元壁”,把不同编程范式中优秀的元素放在一起。

可以通过设计,模拟出其他编程范式中的元素
程序设计语言的发展趋势也是要融合不同编程范式中优秀的元素
学习不同的编程范式,已经成为每个程序员的必修课。

学习不同的编程范式,将其中优秀的元素运用在日常工作中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/162226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Karl Guttag:Quest Pro透视效果差,并不适合商用

AR/VR光学专家Karl Guttag曾指出,基于VST透视的AR虽然绕开了光学透视AR的一些局限,但VST透视依然存在运动延迟、余光视觉透视效果、分辨率、IPD不匹配等多种问题。的确,VST透视AR的结构、原理比光学透视AR更简单,但它同样需要解决…

(二十)正则表达式

目录 前言: 1.概述: 2.正则表达式体验: 3.正则表达式字符 4.正则表达式在字符串方法中的使用 5.代码演示: 6.正则表达式支持爬取信息 7.代码演示: 前言: 正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regex…

SpringCloud-Netflix学习笔记05——Eureka模拟实现简单集群

前言 对于Eureka注册中心来说,如果只有一个注册中心的话,如果注册中心崩了,那么里面的服务全部用不了,系统就会崩溃。为了避免这个问题,我们可以搭建一个注册中心的集群,几个注册中心互相关联,如…

程序员别死背面试八股文了,这种面试题才是未来主流。。。

目录: 面试官为啥要出这样一个开放式问题生产消费模型及核心数据结构支撑TB级数据写入的分布式架构数据宕机场景下的高可用架构支持数据不丢失的ack机制最后的总结 1、面试官为啥要出这样一个开放式问题 这篇文章简单给大家来聊一个互联网大厂的Java面试题&#x…

【Git 从入门到精通】一文摸透Git中的分支操作

文章目录一、什么是分支?二、分支中的常用命令三、上手分支1.查看分支2.创建分支3.修改分支4.切换分支5.合并分支6.解决冲突四、分支操作原理分析一、什么是分支? 在版本控制过程中,同时推进多个任务,为每个任务,我们…

肠道核心菌——戴阿利斯特杆菌属 (Dialister)

谷禾健康 戴阿利斯特杆菌属 (Dialister) ✦ Dialister(戴阿利斯特杆菌属)是小的、厌氧或微需氧的革兰氏阴性球状或杆状菌,因次也被翻译成小杆菌属。 Dialister菌是人体肠道菌群中的一种常见菌种。该菌属物种被发现出现…

基于 Hutool 的抽奖实现与原理

前言 先大概描述下 hutool 工具是如何根据权重进行抽取,后面再结合源码进行讲解。 假设有如下奖品以及对应的权重: 奖品名称权重奖品数量谢谢参与0.76010积分0.4550IPhone 140.055Mac Book Air0.011 需要注意 谢谢参与 也算是一种奖品,因为…

SpringCloud-Netflix学习笔记04——Eureka注册中心搭建

前言 Eureka注册中心相当于Zookeeper注册中心,思想是类似的,只不过Zookeeper需要在本机上下载一个服务客户端,直接启动客户端即可,而Eureka注册中心需要我们自己动手搭建,不过也不难。 搭建步骤 1、新建一个Maven项目…

PySpark数据计算中常用的成员方法(算子)

目录 一.回顾 二.数据计算 map算子 演示 flatMap算子 演示 reduceByKey算子 演示 练习案例1 需求 解决步骤 完整代码 filter算子 演示 distinct算子 演示 sortBy算子 演示 练习案例2 解决步骤 完整代码 三.总结 一.回顾 1.RDD对象是什么?为什么要使用它? RDD对象称…

SegFormer学习笔记(1)安装

一、源码:https://github.com/sithu31296/semantic-segmentation我并没使用SegFormer的官方源码,那个mmcv特磨人了,各种奇葩配置错误。二、环境配置新建conda环境conda create -n segformer3715 python3.7.15 选用python3.7.15(纯粹的3.7.0版…

计算机原理四_内存管理

目录儿三、内存管理3.1 内存管理基础3.1.1存储器的多层结构3.1.2 进程运行基本原理进程的装入3.1.3 内存扩充3.1.4 内存的分配3.1.4.1连续分配3.1.4.2非连续分配3.1.4.2.1基本分页存储管理3.1.4.2.2基本分段存储管理3.1.4.2.3 段页式管理3.2 虚拟内存管理3.2.1 虚拟内存的概念3…

【BP靶场portswigger-客户端11】跨站点脚本XSS-10个实验(下)

前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员&…

【Go基础】函数和面向接口编程

文章目录一、函数1. 函数的基本形式2. 递归函数3. 匿名函数4. 闭包5. 延迟调用defer6. 异常处理二、面向接口编程1. 接口的基本概念2. 接口的使用3. 接口的赋值4. 接口嵌入5. 空接口6. 类型断言7. 面向接口编程一、函数 1. 函数的基本形式 // 函数定义:a,b是形参 …

【测试】自动化测试

努力经营当下,直至未来明朗! 文章目录一、自动化概述二、自动化测试的分类三、自动化测试工具:selenium四、一个简单的自动化用例五、Selenium常用方法1. 查找页面元素:2.元素的定位(By类)小结普通小孩也要…

Java中this的用法

一、this关键字 1.this的类型:哪个对象调用就是哪个对象的引用类型 二、用法总结 1.this.data; //访问属性 2.this.func(); //访问方法 3.this(); //调用本类中其他构造方法 三、解释用法 1.this.data 这种是在成员方法中使用 让我们来看看不加this会出现什…

ArcGIS基础实验操作100例--实验95平滑处理栅格数据

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 空间分析篇--实验95 平滑处理栅格数据 目录 一、实验背景 二、实验数据 三、实验步骤 (1&…

ST算法解决BMQ问题详解(图文并茂,保证看懂)

一.RMQ问题的概念RMQ(Range Minimum/Maximum Query)问题,简单说就是求区间最值问题,是求区间最大值或最小值,即范围最值问题,若是简单的单次询问或者是区间长度很短的询问,可以用暴力的方法来实…

【web安全】——文件上传漏洞

作者名:白昼安全主页面链接: 主页传送门创作初心: 舞台再大,你不上台,永远是观众,没人会关心你努不努力,摔的痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷座右铭…

【寒假第2天】LeetCode刷题

🌈一、选择题 👿第1题: 下面给出的四种排序法中( )排序法是不稳定性排序法A.插入排序 B.冒泡排序 C.归并排序 D.堆,希尔排序,快速排序 答案:D 为啥堆排序是不稳定的&am…

SCA 工具:开源安全威胁一手掌控

1、什么是 SCA SCA(Software Composition Analysis)软件成分分析,通俗的理解就是通过分析软件包含的一些信息和特征来实现对该软件的识别、管理、追踪的技术。我们知道在当今软件开发中,引入开源软件(注 1)到你的项目中&#xff…