2015062802 - EffactiveJava笔记 - 第40条 谨慎设计方法签名

   第40条 谨慎设计方法签名

   20150628  星期日 北京

   本条目是若干API设计技巧的总结,这些设计技巧有助于使你的API更容易学习和使用,并且比较不容易出错.

   谨慎地选择方法名称.方法的名称应该始终遵循标准的命名习惯.首要目标应该是选择易于理解的,并且与同一个包中的其他名称风格一致的名称;第二个目标应该是选择与大众认可的名称(如果存在的话)相一致的名称.如果还有疑问,请参考Java类库的API,尽管Java类库的API中也有大量不一致的地方,考虑到这些Java类库的规模和范围,这是不可避免的,但它还是得到相当程度的认可.

 

   不要过于追求提供便利的方法.每个方法都应该尽其所能.方法太多会使得类难以学习,使用,文档化,测试和维护.对于接口而言,这无疑是正确的.方法太多会使接口是实现者和接口用户的工作变得复杂起来.对于类和接口所支持的每个动作,都提供一个功能气短的方法.只有当一项操作被经常用到,才考虑为它提供快捷方式.如果不能确定,还是不提供快捷为好.

   [上面的意见我感触深刻,现有项目的返回值类中,有太多快捷方式方法,需要很多时间去理解,还不如提供构造方法对返回值对象进行构造,省却查看,理解方法的时间]

 

   避免过长的参数列表.目标是4个参数,或者更少.因为大多数程序员都无法记住更长的参数列表.如果你填写的方法超过这个限制,那么你的方法的复用性就非常差.除非不断参考已有文档.最佳的实践就是简短的参数列表.相同类型的长参数格列尤其有害(说的太好了,我曾经深受其害),API的用户不仅无法记住参数的顺序,如果不小心弄错参数顺序,程序依旧可以编译和运行,但是和设计的初衷完全不同的运行.[从可读性,复用性,可用性而言,长参数的方法签名都是极差的实践!]

   如何缩短过长的参数列表呢?有三种方法.

   第一种方法把方法分解成多个方法,每个方法只需要参数的一个子集.

   这样做可能导致方法过多,那么如何解决呢?可以通过它们正交性,以减少方法的数目.(什么是正交性呢?看看案例)

   例如考虑java.util.List接口,没有提供”在子列表(sublist)中查找元素的第一个索引和最后一个索引”的方法,这两个方法都需要三个参数.(这两个方法是两个方法呢?).

   List接口提供subList方法, subList方法需要两个参数,返回子列表的视图. subList方法可以与indexOf和lastIndexOf方法结合起来,获得期望的功能,而这两个方法分别只有一个参数,而且,subList方法可以与其他任何”针对List实例进行操作”的方法结合起来,在子列表上执行任意的计算.[真心没太懂,举例的操作正常不就是这么处理吗?]

 

   第二种方法是创建辅助类,用来保存参数的分组.这些辅助类一般为静态成员类(参考第22条),如果一个频繁出现的参数序列可以被看做代表某个独特的实体,则建议使用这种方法.

   例如,假设你正在编写一个表示棋牌游戏的类,你会发现需要经常传递一个两参数的序列来表示纸牌的点色和花数.如果增加辅助类来表示一张纸牌,并且把每个参数序列都换成这个辅助类的单个参数,那么这个纸牌游戏类的API以及它的内部表示都会得到改进.

   [例如,很多类需要查询时候,都要查询生成时间,需要某个时间段内的数据,需要两个字段开始时间和结束时间,那么就可以将开始时间和结束时间做成辅助类]

 

   第三个方法是结合以上两种方法,从对象构建到方法调用都采用Builder模式.如果方法带有多个参数,尤其某些参数是可选的,最好定义一个对象表示所有参数,并允许客户端在这个对象进行多次setter调用,每次调用都设置一个参数,或者设置一个较小的相关集合.一旦设置了需要的参数,客户端就调用对象的执行方法,它对参数进行最终的有效性检查,并执行实际的计算.

   [第三种方法是我使用的,越看此书,感觉自己的实践和书中描述的很吻合啊!]

 

   对于参数类型,优先使用接口而不是类.只要有适当的接口可用定义参数,那么就优先使用接口,而不是使用接口的实现类.[为什么呢?这样的设计扩展性好.符合面向对象设计原则,凡是父类出现的地方都可以用子类替换掉.]

   例如:在编写方法使用HashMap类作为参数,还是使用Map接口作为参数呢?

   如果使用HashMap做参数,那么你只能传递HashMap对象;

   如果使用Map接口做参数,那么你可以传递Hashtable,

   HashMap,TreeMap,等等,或者是任何有待于将来编写的Map实现.

   所以可以看出使用类而不是接口,会限制客户端只能传递特定的实现,如果碰巧输入的数据是其他形式,就会导致不必要,且非常昂贵的拷贝操作.

   对于boolean类型,要优先使用两个元素的枚举类型.为什么这么操作呢?让代码更加容易阅读和编写.尤其使用IDE的时候,便于以后添加更多选项.

   例如,可能会有Thermometer类型,它带有静态工厂方法,而这个静态工厂方法的签名需要传递枚举的值:

   public enum TemperatureScale { FAHRENHEIT, CELSIUS}

   Thermometer.newInstance(TemperatureScale.CELSIUS)不仅比Thermometer.newInstance(true)更有用,并且可以将未来发行版本中将KELVIN添加到TemperatureScale中,无需非得给Thermometer添加新的静态工厂中,还可以将依赖温度刻度单位的代码重构到枚举常量的方法中

   [大部分都遵守了,只有boolean使用枚举没有做]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值