- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章优雅整洁的 Java 代码命名技巧,风之极·净化由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
合格的程序员不仅仅是让代码跑起来,而是要做到代码整洁,只满足为了能让编译器通过编译,机器能跑就行而写代码的程序会算不上开发者,码农都不算.
好的命名能体现出代码的特征,含义或者是用途,让阅读者可以根据名称的含义快速厘清程序的脉络.
本篇分享如下代码命名套路来提高我们代码命名:
我相信每个程序员都被某些人的垃圾代码恶心过,导致开发进度被严重延缓、性能差劲、bug 多.
每次新增和修改代码如履薄冰,我们只有对那堆腐朽的代码了然于胸才敢修改.
随着时间推移,团队生产力下降,所有人都抵触这个项目,对其束手无策.
新手不熟悉原来的场景和设计,不知道如何修改才符合实际意图,导致更容易出现混乱.
最后,开发团队产生了抵触心理并造反了,再也无法忍受在这个垃圾代码基础上做开发,而管理层不愿意投入资源重新设计.
一个优秀的开发者应该时刻保持代码整洁,无关 deadline.
为什么会写出垃圾代码呢?
有的人可能会说,需求变化违背了最初的设计、排期太紧没法干好...... 。
其实,这是一种不专业的托词.
推进进度是产品经理他们该干的,虽然痴迷于进度,但是多数产品经理也会期望有良好的可拓展代码以便应对市场变换莫测的需求.
连海誓山盟的爱情都会变,又如何做到需求不会改变呢?
所以我们比他们更加重视代码质量,才能应对变化的需求.
保护代码持续整洁优雅是每个优秀开发者都应该遵守的原则.
混乱的代码只会拖慢未来的开发进度,唯一加快进度的方法:始终尽可能保持代码优雅整洁.
好比医生在做手术之前要先消毒,你说消毒太耗时间了,直接拿刀子整吧.
作为专业的医生你会照做么?
作为专业的程序员,我们要了解代码变坏的风险并坚持保持代码质量.
代码质量评判需要综合各种因素得到的,我们并不能从单一的维度去评判.
比如代码可读性好,但是空间与时间复杂度高,这并不能算得上是好代码.
好的代码应该具备:易拓展和维护、简洁(只做好一件事)、可复用性强(没有重复代码)、能快速写出单元测试。可读性强、没有副作用(做了名称以外的工作).
在不破坏原来的代码设计下,可以简单快速的修改和添加代码实现功能拓展.
简单地说就是预留了拓展点,将新代码放在设计的可拓展点,不会因为新增一个功能而改动大量原始代码.
对于开发而言,我们维护旧代码的时间超过新项目新代码的时间.
代码的可维护性就变得很重要,也就是说代码分层清晰、模块划分精当,满足高内聚低耦合、抽象出合理的接口,面向接口编程就意味着有较好的可维护性.
同样的代码,熟悉他的资深工程师会觉得很容易维护,而新人因为不熟悉代码,不懂设计模式而无法理解.
所以,易拓展具有主观性,我们需要提高基础技能才有资格说代码是否易拓展和维护.
单一职责:每个函数、每个类、每个模块只专注于一件事.
不要设计大而全的类或者函数,我们需要将他们拆分成更细粒度功能更加单一的类.
它不会隐藏设计者的意图,干净利落的抽象和直截了当的控制语句.
我们应该让每个函数每行代码简单、逻辑清晰。这样的话,类依赖和被依赖的类也会变少,减少耦合度.
需要注意的是,也不能拆分太细,否则就会破坏内聚性.
高手,就是用最简单的方法去解决复杂问题.
在开发过程中,我们应该尽可能抽象出「变与不变」,复用已经存在的代码,不要写重复的代码.
比如运用「封装、继承、抽象、多态」特性,代码封装成模块,隐藏变化的细节,暴露不变的接口.
把业务与非业务的代码逻辑分析,抽象成通用的框架、工具类等.
比如应用模板方法设计模式将不变的算法逻辑框架定义出来,把变化的点延迟到子类重写.
代码的可测试性差,比较难写单元测试,那基本上就能说明代码设计得有问题.
试想下,如果一个类大而全,有一个方法依赖了十几个外部对象才能完成工作,耦合严重.
当你在编写单元测试的时候,需要 mock 十几个依赖对象和数据.
那说明这个代码糟透了,需要合理拆分和设计.
软件设计大师 Martin Fowler 说过:「Any fool can write code that a computer can understand. Good programmers write code that humans can understand.」 。
翻译成中文就是:"任何二货都会编写计算机能跑的代码。优秀的程序员能够编写人能够理解的代码。” 。
而可读性就会涉及到编码规范、命名、注释、函数职责是否单1、长度是否精简.
有数据显示读代码的时间与写代码的时间比例超过 10:1,并且编写当前代码的难度,取决于读周边代码的难度.
所以我认为可读性强是最重要的一点.
开发过程后命名随处可见,我们给变量、方法、参数、类、包命名.
而命名的好坏会影响我们的可读性,我们不妨从命名作为切入口来写好代码.
在开发过程中,一旦发现更好的名称,就换掉旧的.
一个变量、方法、或者类的名称应该展示出它该有的功能。根据名字我们能知道它能做什么事情,如何使用.
如果一个名称需要大量注释来补充避免使用者跳坑,那就是糟糕的名字.
你会疑问,为啥索引是从 1 开始?为啥 <= 5。除此之外, i 与 1 极其相似,难以区分.
正确的方式应该使用实际含义的名字让人理解这么写的目的,否则维护的人将痛苦不堪.
UltimateAssociatedSubjectRunBatchServiceImpl,当我们看到这样的类名,是不是不知道怎么读,也不知道如何搜索和定位,更不知道到底表达的意思是什么,可能命这个名字的人还以为准确表达,其实是“王大妈的裹脚布,又臭又长”.
原本的业务含义是:执行关联主体任务相关业务类.
鉴于此,我们第一步要避免使用生僻字,可以命名为LinkSubjectServiceImpl ,清晰简单的表达出关联主体的业务逻辑都在该类.
尽量不要使用不同之处较小的名称,这样让他人无法一眼区分两个名称是啥意思.
例如:函数 deleteIndex 和函数deleteIndexEx,这两个函数名区别很小了,加之函数 deleteIndexEx后面Ex还是缩写,也不知道是什么意思,所以他人只能去看函数内容才能明白两者的区别.
让人抓狂,他们到底是一个东西还是不同的?差别在哪?没有两年脑血栓写不出这样的.
下面是一个生成文件并提供下载功能的接口.
我们会疑惑,downLoadFiles 与 fileDownload 到底有啥区别?为啥要调用两次.
这种真的是十年脑血栓才写得出来.
downLoadFiles 的功能是创建将 files 打包成 zip 文件,而 fileDownload则是把指定的文件输出给浏览器下载.
所以 downLoadFiles 应该命名为 createZipFile用于合理区分避免误人子弟.
上面都是废话命名,别人你怎么知道到底该调用那个方法?
哪个表示订单明细?还是历史订单,还是全部订单查询,废话是另一种没有意义的区分.
Order、OrderInfo、OrderData,他们名称相同 ,意思却无差别,属于毫无意义的废话。如果缺少明确约定,变量moneyAmount就与money没区别.
Variable一词永远不应当出现在变量名中。Table一词永远不应当出现在表名中.
比如 Order类,在该上下文中,没必要给每个成员变量重复添加 order 这个前缀单词,直接命名为 createTime、num.
因为我们可以借助 Order 这个上下文来获取信息.
可读指的是不要使用一些生僻字,难以发音的单词.
可搜索是便于利用 IED 的自动补全和搜索功能,能根据我们的命名规范快速定位想要找的类或者方法等.
名称读不出来,在讨论的时候就好像是一个沙雕.
哎,那个「treeNewBeeAxibaKula」类是什么作用?
听到这样的名字尴尬癌都犯了.
使用一些生僻字,犹如「王大妈的裹脚布,又长又臭」,没有两年脑血栓写不出这样的垃圾代码.
IED 很智能,当我们输入 「Hash」的时候,会列举出所有 Hash 相关的类.
命名的时候最好符合项目命名习惯,列表数据查询大家使用 listXXX,你就不要用 queryXXX,统一命名规范,很重要.
包名统一使用小写,点分隔符之间有且仅有一个自然语义的英文单词或者多个单词自然连接到一块(如 springframework,deepspace 不需要使用任何分割).
包名的构成可以分为以下几四部分【前缀】 【发起者名】【项目名】【模块名】.
以下表格授权于「Java 填坑笔记」 。
常见的前缀可以分为以下几种:
类名使用大驼峰命名形式,应该使用名词或者名词短语,比如:Customer、Account.
避免使用 Manager、Processor 等动词.
接口名除了用名词和名词短语以外,还可以使用形容词或形容词短语,如 Cloneable,Callable 等,表示实现该接口的类有某种功能或能力.
方法命名一般为动词或动词短语,与参数或参数名共同组成动宾短语,即动词 + 名词。一个好的函数名一般能通过名字直接获知该函数实现什么样的功能.
注:Prefix-前缀,Suffix-后缀,Alone-单独使用 。
单词 | 意义 |
get获取 | set 设置 |
add 增加 | remove 删除 |
create 创建 | destory 移除 |
start 启动 | stop 停止 |
open 打开 | close 关闭 |
read 读取 | write 写入 |
load 载入 | save 保存 |
create 创建 | destroy 销毁 |
begin 开始 | end 结束 |
backup 备份 | restore 恢复 |
import 导入 | export 导出 |
split 分割 | merge 合并 |
inject 注入 | extract 提取 |
attach 附着 | detach 脱离 |
bind 绑定 | separate 分离 |
view 查看 | browse 浏览 |
edit 编辑 | modify 修改 |
select 选取 | mark 标记 |
copy 复制 | paste 粘贴 |
undo 撤销 | redo 重做 |
insert 插入 | delete 移除 |
add 加入 | append 添加 |
clean 清理 | clear 清除 |
index 索引 | sort 排序 |
find 查找 | search 搜索 |
increase 增加 | decrease 减少 |
play 播放 | pause 暂停 |
launch 启动 | run 运行 |
compile 编译 | execute 执行 |
debug 调试 | trace 跟踪 |
observe 观察 | listen 监听 |
build 构建 | publish 发布 |
input 输入 | output 输出 |
encode 编码 | decode 解码 |
encrypt 加密 | decrypt 解密 |
compress 压缩 | decompress 解压缩 |
pack 打包 | unpack 解包 |
parse 解析 | emit 生成 |
connect 连接 | disconnect 断开 |
send 发送 | receive 接收 |
download 下载 | upload 上传 |
refresh 刷新 | synchronize 同步 |
update 更新 | revert 复原 |
lock 锁定 | unlock 解锁 |
check out 签出 | check in 签入 |
submit 提交 | commit 交付 |
push 推 | pull 拉 |
expand 展开 | collapse 折叠 |
begin 起始 | end 结束 |
start 开始 | finish 完成 |
enter 进入 | exit 退出 |
abort 放弃 | quit 离开 |
obsolete 废弃 | depreciate 废旧 |
collect 收集 | aggregate 聚集 |
命名目的都是为了让代码和工程师进行对话,增强代码的可读性,可维护性。优秀的代码往往能够见名知意.
本文转载自微信公众号「码哥字节」 。
原文链接:https://mp.weixin.qq.com/s/TEuRxrBFU9CfjmO3vGqtxA 。
最后此篇关于优雅整洁的 Java 代码命名技巧,风之极·净化的文章就讲到这里了,如果你想了解更多关于优雅整洁的 Java 代码命名技巧,风之极·净化的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
您如何优雅编码同一tableView中的两种类型的单元格? 显然我可以这样: NSDictionary *cellInfo = [_userInformation objectAtIndex:inde
假设我正在编写一个仅包含标题或主要包含标题的库,并且具有以下代码: using my_type = int; namespace detail { inline void foo() { my
我正在使用复选框和输入进行一系列启用/禁用选择,我想知道我是否可以使用循环、变量或复合语句来简单地处理这个js?感觉就像是使用大量代码来实现相对简单的功能。 这是我正在做的事情的一个 fiddle :
我正在尝试为来自维基百科的 API 响应编写一个解析器。它真的很困惑,我已经求助于旧的 RegEx 来清理大部分东西。然而,我坚持这一点。考虑一个字符串: var a ="[[December 1]
我正在通过一个 channel 接收多个消息,并在对其进行迭代之后,我想保留最后一个元素以供进一步使用。我的第一个(可能很糟糕!)方法是声明一些变量,然后在每个循环中分配它。 let last = 0
我正在编写一个 PHP Web 应用程序,它将在不久的将来在生产环境下运行,而不是使用非用户友好的 die() , 我想我会想出一个 Class处理错误消息。 基本上,我的思考过程是这样的: 如果 W
我们有 elb 负载平衡 2 台运行 tomcat 作为应用程序服务器的 WAS 机器。要实现AWS环境下的不间断部署,我们应该, 选择部署目标 WAS。 让它停止来自 elb 的交易。(elb 暂停
何为pythonic? pythonic如果翻译成中文的话就是很python。很+名词结构的用法在中国不少,比如:很娘,很国足,很CCTV等等。 我的理解为,很+名词表达了一种特殊和强调的意味。
认为已经有对此的答案,但找不到。我一直在以某种方式解析方法选项,并想检查并确保它是最优雅/最简洁的方式。 这是我通常做的: def some_method *args options = args
我正在清理我的一个旧项目。它必须做的一件事是——给定笛卡尔网格系统和网格上的两个正方形,找到所有正方形的列表,连接这两个正方形中心的线将通过这些正方形。 这里的特殊情况是所有起点和终点都被限制在正方形
如何使系统 ( SystemB1 ) 访问另一个系统 ( SystemA::sub ) 的字段,就好像它是自己的字段一样? SystemA是一个拥有自己领域的实用系统 Sub* sub . Syste
我有一个包含约 8.000.000 条记录的 MySQL 数据库。因为我需要处理所有这些,所以我使用 BlockingQueue 作为生产者从数据库读取数据并将 1000 条记录放入队列中。 Cons
我正在让我的 HTTP 服务器正常关闭。我从帖子中获取了提示 here ,到目前为止,我的代码是这样设置的: func start() { //...... //START HTTP/
示例脚本只是“wc -m”命令的包装器,简单的符号计数器。我尝试只用“teststrings” slice 元素提供输入。并在输出监听器 goroutine 接收每个字符串的符号数。寻找一种让“wc”
我想干净/优雅地关闭 Internet Explorer。 taskkill 会关闭它,但是当重新打开它时,它会询问您是否要重新打开上一个 session 。 最佳答案 尝试 CloseMainWin
Haskell 的简洁和优雅给我留下了深刻的印象。但我在 .Net 公司工作,所以当我可以使用 F# 时我会使用它——我可能是全国数百个使用它的人中唯一的一个。 ADO.NET 或 F# 是否提供像
如果我们不想在我们的类中实现 init 方法,并且记住 NSObject 中的 init 只返回一个没有初始化的对象实例,如果我们已经得到了,我不明白调用 init 的意义带有分配的实例。我已经尝试过
我们的组织中有许多初级 Delphi 开发人员,作为向他们教授 Delphi 过程的一部分,我希望他们能够看到“干净”、编写良好、设计良好的 Delphi 代码。 我要寻找的一些标准包括: 优秀的类(
我有一个 3D 图像扫描(形状:335x306x306,总元素:31368060),我想用相同大小的 3D bool 掩码来掩盖它以返回相同大小的蒙版图像。 当我简单地用掩码索引数组时: masked
如何使适配器类适本地支持 const 和非 const 底层数据? 具体例子 RigidBody是描述对象物理属性的类。 这是其非常简化的版本(1D):- class RigidBody{ f
我是一名优秀的程序员,十分优秀!