java 枚举 菜鸟_2个菜鸟Java常量和枚举陷阱

java 枚举 菜鸟

在对Java和Groovy代码进行的各种代码审查中,我经常看到魔术数字和其他随机字符串散落在整个代码库中。

例如,下面的(Groovy)代码段中的4.2是一个神奇的数字:

if (swashbuckle >= 4.2) {...
}

4.2是什么意思?

我的建议是将一个数字提取为一个常数,并为其赋予一个有意义的意图显示名称,以便我们所有人都可以继续理解我们的代码。

每次平台特定的常数

重构成

if (swashbuckle >= MAX_ALLOWED_CAPACITY) {...
}

即使是初学者,也可以理解The Constant的值,并开始将各地的值提取为常量。 当我谈论枚举时,编写可读代码的可能性更大,但是经验不足的开发人员很快就会陷入以下陷阱。

陷阱#1全球Über-Constants文件

应尽可能避免使用全局常量文件,例如

class Constants {private static final String PEACH_FLAME = "PFL"private static final int MAX_TOOGIT = 17private static final int MIN_TOOGIT = 8private static final String USER_NAME_AGE_PROPERTY =  "age"private static final String USER_NAME_FLOPPY_PROPERTY =  "floppy"private static final int CUSTOM_HYSLERIA_DONE = -99private static final List<String> WOBBA_RANGE = ['BZ, 'FLL', 'BZZ']// dozens of other constants...

引用StackOverflow总结得很好 :

我强烈建议不要使用单个常量类。 当时这似乎是个好主意,但是当开发人员拒绝记录常量并且该类增长到包含多达500个完全不相关的常量(与应用程序的完全不同的方面)时,这通常会变成完全不可读的常量文件。 代替:

  • 如果可以访问Java 5+,请使用枚举为应用程序区域定义特定的常量。 对于这些常量,应用程序区域的所有部分都应引用枚举,而不是常量。 您可以声明类似于声明类的枚举。 枚举也许是Java 5+的最(也是唯一的)有用的功能。
  • 如果您的常量仅对特定类或其子类之一有效,则将其声明为protected或public,然后将其放在层次结构中的顶级类上。 这样,子类可以访问这些常量值(如果其他类通过公共访问它们,则这些常量不仅仅对特定的类有效……这意味着使用该常量的外部类可能与包含该常量的类紧密耦合。常数)
  • 如果您有一个定义了行为的接口,但是返回值或参数值应该特别,那么在该接口上定义常量是完全可以接受的,以便其他实现者可以访问它们。 但是,请避免创建仅用于保存常量的接口:它可能与仅为保存常量而创建的类一样糟糕。

单个类(例如我们上面的Constants示例)很快就变成了一切 。 新秀开发人员认为,他通过将魔术数字和魔术字符串提取为常量来遵循良好的(代码审查)建议,但是团队很快就承担了新的维护负担。

如果你发现自己(或你的团队)这样做,请把负责任的车主如用户相关的常数常量UserService在和wobba相关常量WobbaConverter -不管它是什么

还请阅读上面注释中有关枚举的部分,因为常量并不是镇上唯一的孩子。 有时我的建议是……

首选枚举

如果您的常数可以很好地建模为枚举,请考虑枚举结构。 枚举比简单的常量更具通用性 ; 它们是类,可以包含属性和方法。

在负责任的父类中。

更喜欢

class Person {enum Gender { M, F }String nameGender gender
}

过度

class Person {static final String GENDER_MALE = 'M'static final String GENDER_FEMALE = 'F'String nameString gender
}

或作为使用它的班级附近的一个单独的班级 (如果它变大)。 具有功能名称的enum类的一个很好的例子是例如一些相关的(技术)数据

/*** Represents medicine domain codes.*/
public enum MedicineCode {/** Diagnosis e.g. "Muscle damage". */DIAGNOSIS("X357"),/** Units in medicinal context e.g. "cc/ml". */MEDICINE_UNIT("X523"),/*** Cause codes for diagnosis = 'Masitis' e.g. "E.coli (ECO)".*/CAUSE_CODE("X536"),/** TreatmentType e.g. "Antibiotics". */INTERVAL_TYPE("X520"),
MedicineCode(String code) {this.code = code;}private final String code;public String code() {return code;}/*** Find a {@link MedicineCode} by given String code.** @param code The code e.g. "X261"* @return found medicine code, or null*/public static MedicineCode findByCode(String code) {values().find { it.code() == code }}@Overridepublic String toString() {return name() + "(" + code() + ")"}
}

每当需要表示一组固定的常量时,都应使用枚举类型。 因此,新秀开发人员认为他通过将内容提取到枚举,封装技术数据,使用功能名称等方式来遵循良好的(代码审查)建议,但通常会陷入

陷阱#2定义枚举,但未正确使用它们

因此,如果您最初具有以下方法和调用:

Medicine findMedicineForDomainCode(String code)// which you call like: 
String intervalTypeCode = "X520"
findMedicineForDomainCode(intervalTypeCode)

并且您可能会引入像MedicineCode这样的枚举(请参见上文),将所有这些特定于域的技术(例如数据库“ X…”)代码(例如“ X520”)封装在一起,然后不要这样做:

Medicine findMedicineForDomainCode(String domainCode)// which one keeps calling like:
String intervalTypeCode = MedicineCode.findByCode("X520")
findMedicineForDomainCode(intervalTypeCode)

我见过像这样的团队。 是的,有一个带有值的枚举类型,但是团队在整个代码中并不十分了解如何处理它们。

枚举

第一步是直接引用枚举 。 某些菜鸟开发人员通常最初已经理解了这一点,这取决于他们是否遵循Oracle Java Enum Types教程或类似内容,但通常会导致如下所示:

Medicine findMedicineForDomainCode(String code)// which one calls like:
String intervalTypeCode = INTERVAL_TYPE.code()
// WRONG! still using Strings here
findMedicineForDomainCode(intervalTypeCode)

有了枚举意味着我们现在可以键入所有内容,包括返回类型和方法参数

只是将枚举用作容纳字符串的容器并不是我们这样做的原因:为了获得更好的类型安全性和可读性,您应该重构代码中的所有内容,以便将域代码用作MedicineCode枚举的字符串类。

更好:

// first refactor method parameter from String to MedicineCode
Medicine findMedicineForDomainCode(MedicineCode code)// now just pass an enum value
findMedicineForDomainCode(INTERVAL_TYPE)

然后,直到那时,在最后一个可能的时刻,您需要实际封装的String代码(“ X520”)–可以从枚举值中提取它。

希望这有助于定义常量和使用枚举。 我无法涵盖使用适当设计的枚举类型可能具有的所有“有效”用法和OO优势的所有其他情况,但是希望本文能够防止Java新手陷入所描述的陷阱。

翻译自: https://www.javacodegeeks.com/2016/04/2-rookie-java-constants-enums-pitfalls.html

java 枚举 菜鸟

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

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

相关文章

python正则_python的正则表达式

上次小编写了正则表达式的用法&#xff0c;今天就小编就讲讲正则表达式再python中的应用&#xff0c;在python中想使用正则表达式就需要导入re模块。接下来小编将先介绍re模块中几个常见的函数findall:re.findall(‘正则表达式’&#xff0c;‘待匹配的内容’)例1&#xff1a;输…

公里与英里的换算c语言函数_60迈=60码=60公里?这三者天壤之别,可别搞错了

说到行车速度&#xff0c;大家经常用的是这三个单位&#xff1a;码、迈、公里/时&#xff0c;很多人以为这三者是同一个意思&#xff0c;都是每小时多少公里。实际上这三者并不等同&#xff0c;下面小编科普一下这几个词的差异。码1码不等于1公里&#xff0c;而是等于0.9144米&…

php3.2.3分组查询,ThinkPHP3.2.3版本如何设置应用分组

鑫强已经解决了我的解决方法是创建两个入口文件实际上我的目的就是想要达到两个模块共用一个配置文件和公共函数文件我的解决方法是在项目根目录下建立两个入口文件一个是Index.php与Root.php两个入口文件其中是这样写的Index.php{<?php #前台入口文件 header(Conte…

C++ 11 深度学习(一)auto、头文件防卫、引用、常量

1.数组初始化 int a[]{ 1,2,3,4,5 }; 2.C11 auto auto可以在声明变量的时候根据变量的初始值的类型自动为此变量先择合适的类型&#xff0c;声明时要赋予初值。 auto自动推导发生在编译期间 auto A 10;//A会被自动推导为int类型 3.头文件防卫式声明 作用:防止头文件重…

android 在什么情况下会主动gc_Python 什么情况下会生成 pyc 文件?

作者&#xff1a;折木奉太郎(经授权转载)来源&#xff1a;https://www.zhihu.com/question/30296617/answer/112564303作为 Python 爱好者&#xff0c;需要了解 .py 脚本的基本运行机制及特性&#xff1a;在很多工作上&#xff0c;Python 的运行流程基本上取决于用户&#xff0…

【IP协议头分析】

Version 版本号 IHL IP头长度 Type of Service Total Length 总长度 Identification 拆包的唯一标识 Flags 1位保留 &#xff0c; 2位 允许拆包 3位 不允许拆包 Fragment offset 在原包偏移量 Time to Live 时间或路由跳数 Protocol IP中是什么协议类型 Header Check…

乡村野生草药_官方野生蝇群流口水分数

乡村野生草药官方是什么&#xff1f; 标题太小&#xff0c;但有用的贡献。 Wildfly Swarm允许我们创建相当小的自包含应用程序&#xff0c;包括我们从Wildfly Application Server中需要的应用程序。 在这篇文章中&#xff0c;我们将研究与Wildfly Swarm合作使用的Drools分数 。…

obs多推流地址_(无人直播)教程利用OBS推流抖音直播电脑屏幕或PC游戏

目前的火爆程度相信大家都有目共睹&#xff0c;也為部分活躍用戶提供直播功能&#xff0c;開通直播的方法有&#xff1a;①粉絲達到10000粉絲&#xff0c;官方會自動邀請妳開通直播權限。②加入和官方合作的工會&#xff0c;無需粉絲&#xff0c;也可以開通直播權限。開通直播功…

倒数日电脑版_应用日报|iOS 或更名为 iPhoneOS,倒数日 Mac 版上线限时免费

今日推荐倒数日 Days Matter for Desktop免费&#xff0c;macOS 86 MB倒数日 Days Matter 是 iOS 端非常经典的应用&#xff0c;今天它的 Mac 版本上线&#xff0c;限时免费 7 天。它延续了 iOS 端的风格语言&#xff0c;同样能帮你记录生活中重要的日子&#xff1a;例如恋人…

【TPC协议头解析】

Source Port 源端口 Destination Port 目的端口 Sequence Number 数据报编号 (seq)&#xff08;按字节序&#xff09;保证有序 Acknowledgment Number (ACK) 报文应答, 保证可靠性 Data offset 跳到data数据部分 Reserved 保留部分 URG 紧急数据标识 ACK 确认消息…

iphone新旧手机数据传输已取消_如何取消iPhone手机App自动扣费?三种方法让你不再被“偷”...

一直以来苹果手机App这个自动续费真是让大家不胜其烦&#xff0c;钱虽然不多可总是平白无故这里十块&#xff0c;那里二十块的被扣也是不小的浪费&#xff0c;日常生活中为了追追剧、听听音乐、玩玩游戏难免会开通一些App会员而选择自动续费的话每月会费是有不错优惠的&#xf…

【TCP三次握手与四次挥手最强解析】

TCP连接拥塞控制四种方法总结&#xff08;详细简单&#xff0c;稳的一批&#xff09; TCP三次握手 作用&#xff1a;确认seqnumber&#xff1b;确定窗口大小以及最大报文大小 TCP四次挥手 WAIT_TIME状态到CLOSED需要2MSL时间&#xff08;最长单位MSL为2min,一般30s&#xff0…

oracle基础授权,Oracle基础学习3--Oracle创建用户并授权

Oracle服务器端的操作一般如下&#xff1a;1)安装Oracle服务器软件2) 创建数据库(安装时自动创建)3) 配置监听(安装时自动配置)4) 启动Oracle实例5) 创建用户表空间6) 创建新用户并授权下面就开始讲创建用户表空间、创建新用户并授权两项&#x…

mybatis缓存二级缓存_MyBatis缓存与Apache Ignite的陷阱

mybatis缓存二级缓存一周前&#xff0c;MyBatis和Apache ignite 宣布支持apache ignite作为MyBatis缓存&#xff08;L2缓存&#xff09;。 从技术上讲&#xff0c;MyBatis支持两个级别的缓存&#xff1a; 本地缓存&#xff0c;默认情况下始终启用 L2缓存&#xff0c;可选 随…

企业是否应该实现对客户需求的快速响应_CRM系统给企业带来的创新有哪些?如何让销售爱用CRM系统?...

对于现代企业来说&#xff0c;CRM已然成为了一个成熟的项目&#xff0c;是能够给客户带来不菲的价值的。如果应用好&#xff0c;是能够取得提高客户满意度与企业经济效益的双赢成绩的。一、目前&#xff0c;CRM能够给企业带来的业务创新有哪些&#xff1f;1.统一数据CRM系统能将…

junit注释_通过此注释改善您的JUnit体验

junit注释JUnit可能是所有Java项目中90&#xff05;的一部分。 令人兴奋的是&#xff0c;我们很快将拥有支持Java 8的JUnit 5 。 我们最近在博客上发表了一项改进 。 回到JUnit 4领域&#xff0c;有一个小技巧&#xff0c;我只能建议您进行所有单元测试。 只需在此处添加这个小…

lagom的微服务框架_微服务有麻烦吗? Lagom在这里为您提供帮助。 试试吧!

lagom的微服务框架蛋糕支持。 我们很自豪地宣布&#xff0c;新的Apache许可的微服务框架Lagom可在GitHub上使用 &#xff01; 当其他框架专注于打包和实例启动时&#xff0c;Lagom重新定义了Java开发人员构建基于微服务的应用程序的方式。 服务是异步的。 服务内通信由您管理。…

python离线安装包_Python2.7如何离线安装包

1 Python版本是2.7已经在CentOS7系统自带&#xff0c;没有pip&#xff0c;没有互联网环境&#xff0c;需要先安装 backports.ssl_match_hostname-3.4.0.2.tar.gz&#xff0c;直接再CentOS7系统运行以下命令&#xff1a; 解压tar文件 tar -xvf backports.ssl_match_hostname-3.4…