Java枚举类-行为模式最佳实践


  • 博客分类:

下面的主要内容是读了《Effective Java》第二版第30条之后的一些看法和总结。

 

     在面对一大篇的叙述性的知识点介绍时,往往觉得太过乏味,抓不住重点甚至有些力不从心。而采用对比的学习方式,可以明了孰优孰劣,关键特性是什么。第30条关于枚举的介绍,带给我一些感触。

曾和同事讨论如何使用常量,说就用过public static final,不知道枚举,唉╮(╯▽╰)╭是多不关注Java的特性更新啊!

     言归正传,首先就是介绍int枚举模式:

伦理片 http://www.dotdy.com/

     这种方式存在诸多不便,你可以在需要APPLE_FUJI的地方使用ORANGE_NAVEL而不引起任何的编译和运行时异常,一旦常量值发生变化客户端必须重新编译,如果是混用的情况,运行时的行为即使重新编译也是无法确定的,而且往往在数据传递和使用时看到的只是个magic number,遍历int枚举常量也没有可靠的方法。

 

     还有String枚举模式,主要这种方式存在性能问题,因为依赖于字符串的比较操作。

     

     但有一种方式,就比如Integer.MAX_VALUE,Integer.MIN_VALUE,MATH.PI等,分别表示整型数的最大最小值和圆周率,是和具体的类相关联一个属性或者是一个有具体意义的常量值,这样表示是合适的。

   

    Java枚举类型背后的基本想法非常简单:它们就是通过共有的静态final域为每个枚举常量导出实例的类。它们是单例的泛型化,本质上时单元素的枚举。所以使用枚举实现单例是一种有效方式。相对于int枚举模式,Java枚举类型有以下优势:1、枚举类型拥有自己的命名空间,可以允许同名常量(不同命名空间);2、可以增加和重排枚举类型中常量,而无需重新编译客户端;(新增常量自然无法使用)3、toString可以获取常量的字面值;4、常量可任意添加方法和字段。

下面主要围绕文中提到的枚举常量的方法运用,进行下说明,并且发现文中提到的这些使用方式和设计模式的行为模式有些许相似,我称之为枚举的行为模式。

 

一、枚举常量的共同行为

以太阳系的8大行星为例,每颗行星都有质量和半径,通过这两个属性可以计算出表面重力,从而通过物体质量可以获取在某行星上重量,例子中枚举常量两个参数分别表示行星的质量和半径:


下面是计算表面重量的主方法:


结果如下:

Weight on MERCURY is 66.133672

Weight on VENUS is 158.383926

Weight on EARTH is 175.000000

Weight on MARS is 66.430699

Weight on JUPITER is 442.693902

Weight on SATURN is 186.464970

Weight on URANUS is 158.349709

Weight on NEPTUNE is 198.846116

 

行为分析:

每个行星都要计算其表面重量,而行星计算表面重力的公式是不变的,所以每个常量的这个行为是统一的,抽象为一个方法即可,而巧妙之处在于在初始化常量时把表面重力值一同计算出来,计算时直接取值即可。

 

二、枚举常量的不同行为

  影音先锋电影 http://www.iskdy.com/

以操作码为例,加减乘除的实现是不同的。首先是第一种实现方法(一种不好的方法):


这段代码看似可行,但是却很脆弱,如果添加了新的常量,忘了给switch添加判断条件,编译没有问题,运行时却会报异常。而且以面向对象编程的角度来看,面对大量的switch case语句或者if else语句,那一般就是有改进的余地的。

文中提出了一种叫做“(特定常量方法实现)constant-specific method implementations”的一种方法,就是在枚举类型中声明一个抽象方法,在常量中进行实现,代码如下:


这样添加新常量也不会忘记方法实现了,因为编译器会提醒你的。进一步改进就是与具体的常量数值结合起来,利用toString方便的打印算术表达式:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值