方法的度和幽灵方法

本文通过研究Apache Commons IO的FileUtils类,探讨了方法的度(1度和2度)概念,指出度越小的方法越核心。同时引入了幽灵方法的概念,即功能相似的多个方法。文章还介绍了方法约简的重要性,通过实例展示如何从众多重载方法中提炼出关键的①度方法,并提出了方法设计的指导原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

发发神经


在研究Solr源码发现它用到了Apache的commons io包,回想以前在各种场合见过这位“侠客”留下的痕迹,犹如挥之不去的魅影,决心花一天时间好好拜访一下commons io!!正当我撸起了袖子,信心满满,蓄势待发,果然单FileUtils就给了我一个闭门羹……


在研究源码时,类图、时序图能起到很好的辅助作用,而且借助Eclipse调试、链接功能,可以省下很多力气。但是面对粒度更细的方法层,我并没找到很好的解决方案。有时候单一个类中的方法,就有各种跳转调用,我们也被牵着鼻子在Eclipse中跳来跳去。以FileUtils类为例,它是一个工具方法集合共93个方法。里面含有大量的同名或者至少长得可以让你眼花的兄弟方法。下面举一些例子。

copyDirectory4              
copyFile3
iterateFiles2
listFiles2
write6
writeLines7
writeStringToFile6


但其实,一归纳就会发现,很多重载方法归根结底就是一个方法,只不过为了调用的方便,或是省去某个参数代以默认值,或是加了一层包装。有时候需要忽略重载细节,抓住问题的本质,当你再一次看到某个重载方法时,你头脑就会反应“嗯,它其实最后调用的是这个方法”。所以我按照自己的想法,给出了一个阅读源码方法层的解决方案。


方法的度

①指1度方法,②指二度方法。度越小,这个方法越“本质”。而⓪度方法通常表示非装饰的内部方法。


+ listFiles(File, IOFileFilter, IOFileFilter) ①
+ listFiles(File, String[], boolean) ②

- innerListFiles(...) ⓪

+ listFilesAndDirs(File, String[], boolean) ①

- innerListFiles(...) ⓪

- validateListFilesParameters(File, IOFileFilter) ⓪


一般而言,方法的参数个数越多,度会越小,其他重载方法是某些参数缺省值的快捷方法;方法的参数个数相同,同位置参数类型越简单,度会越大,比如含String encode参数的方法会调用含Charset encode的重载方法。

还有一个“一般”规律:参数每减少一个,不是直接调用低一度的方法,而是直接调用①度方法。对我们的启示是:高度方法尽量不要多层嵌套调用重载方法,而是直接调用①度方法;①度方法的设计很重要。

幽灵方法

加下划线__的表示是幽灵方法。


玩过赛车游戏的人可能知道,有些赛车游戏会加入自己以前的赛车轨迹,成为幽灵选手。而一些功能相同的方法总是会有两个,比如返回值为File类型和String,返回值为数组类型和Collection类型,返回值为Collection类型和Iterate类型。


+ listFiles(File, IOFileFilter, IOFileFilter) ①
+ listFiles(File, String[], boolean) ②

- innerListFiles(...) ⓪

+ listFilesAndDirs(File, String[], boolean) ①

- innerListFiles(...) ⓪

- validateListFilesParameters(File, IOFileFilter) ⓪


+ iterateFiles(File, IOFileFilter, IOFileFilter) ②
+ iterateFiles(File, String[], boolean) ③

+ iterateFilesAndDirs(File, String[], boolean) ②


方法约简

+ copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate)
+ copyDirectory(File srcDir, File destDir, boolean preserveFileDate) ②
+ copyDirectory(File srcDir, File destDir, FileFilter filter) ②
+ copyDirectory(File srcDir, File destDir) ③

- doCopyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate, List<String> exclusionList) ⓪


+ write(File file, CharSequence data, Charset encoding, boolean append)
+ write(File file, CharSequence data, boolean append) ②
+ write(File file, CharSequence data, Charset encoding) ②
+ write(File file, CharSequence data) ②
+ write(File file, CharSequence data, String encoding, boolean append) ②
+ write(File file, CharSequence data, String encoding) ③

+ writeStringToFile(File file, String data, Charset encoding, boolean append) ⓪


+ writeLines(File file, String encoding, Collection<?> lines, String lineEnding, boolean append)
+ writeLines(File file, String encoding, Collection<?> lines, boolean append) ②
+ writeLines(File file, String encoding, Collection<?> lines, String lineEnding) ②
+ writeLines(File file, Collection<?> lines, String lineEnding, boolean append) ②
+ writeLines(File file, Collection<?> lines, String lineEnding) ②
+ writeLines(File file, String encoding, Collection<?> lines) ②
+ writeLines(File file, Collection<?> lines, boolean append) ②
+ writeLines(File file, Collection<?> lines) ②

+IOUtils.writeLines(Collection<?> lines, String lineEnding,OutputStream output, String encoding) ⓪


+ writeStringToFile(File file, String data, Charset encoding, boolean append)
+ writeStringToFile(File file, String data, Charset encoding) ②
+ writeStringToFile(File file, String data, boolean append) ②
+ writeStringToFile(File file, String data) ②
+ writeStringToFile(File file, String data, String encoding, boolean append) ②
+ writeStringToFile(File file, String data, String encoding) ③

+IOUtils.write(String data, OutputStream output, Charset encoding) ⓪


约简后

+ copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate) 

+ write(File file, CharSequence data, Charset encoding, boolean append) 

+ writeLines(File file, String encoding, Collection<?> lines, String lineEnding, boolean append) 

+ writeStringToFile(File file, String data, Charset encoding, boolean append) 


单这4个方法,可以约简掉20个方法。


结论

结论一

重载方法中:参数越长,度越低;参数长度相同,类型越复杂,度越低。

我们只需要看那些度为①的方法。


结论二

高度方法尽量不要多层嵌套调用低度重载方法,而是直接调用①度方法;①度方法的设计很重要。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值