编码规范:如何优化一个工具类

159 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

在整理项目工具类的时候,发现很多优化空间,总结出以下一些优化的方向。如果你有其他的优化思路,欢迎评论共同学习。

参考开源写法:完善实现

比如 FileUtils#deleteFile(File file, String[] excludeDir),之前是使用 excludeDir 数组指定不删除的问题,通过开源对类似方法的处理,可以使用官方 FileFilter, 对文件进行过滤

    /**
     * 删除文件 如果是文件夹,则删除文件夹  若是文件,则删除文件
     * @param file       File 文件
     * @param excludeDir 不需要删除的文件目录白名单
     */
    public static void deleteFile(File file, String[] excludeDir) {
        if (file == null) {
            return;
        }
        if (file.isFile()) {
            file.delete();
            return;
        }
        if (file.isDirectory()) {
            if (excludeDir != null && excludeDir.length > 0) {
                for (String dir : excludeDir) {
                    if (file.getAbsolutePath().equals(dir)) {
                        return;
                    }
                }
            }
          // 不是过滤目录,正常删除 代码 略
          ……
        }
    }

将删除文件夹方法部分整改后

fun File.deleteDir(fileFilter: FileFilter? = null): Boolean {
    if (!isDirectory) return false

    if (!exists()) return true

    if (fileFilter != null) {
        if (fileFilter.accept(this)) {
            //目标目录,就是 需要跳过文件,不处理
            return true
        }
    }
    // 后面正常做文件删除处理,代码略
   	……
}

优化之后,在使用上更加清晰,比如

dirFile.deleteAll { pathname ->
	pathname.absolutePath.contains("Module", true)
}

参考官方API 注释说明

  • 参考官方方法注释的说明
  • 中英文问题,有时与其用蹩脚的英文,不如用中文描述清楚

单元测试

  • 尽可能通过单元测试测试工具类方法,提前验证方法是否可用,或者结果是否符合期望

命名优化

在测试调用方法时,是否符合语境,使用时是否顺手 ,可以通过 kotlin 的扩展函数优化工具方法的定义

比如:bitmap.saveBitmap -->bitmap.save;getPathFormUri --> Uri.toPath

方法分类优化,根据功能进行分配

根据使用方确定位置,比如 saveBitmap(Bitmap bitmap. String path ……)

//FileUtils
saveBitmap(Bitmap bitmap. String path ……)

bitmap.save 更容易被联想到(Bitmap 比起 File 更容易先联想到 Image),所以可以放到 ImageUtils 处理 Bitmap 相关

在之前的文章里也提到过工具了的痛点是找不到:明明有这个方法,使用的时候却找不到。我们可以参考原来的使用场景,辅助分配(方法放到哪个工具类里)和确认方法是否有保留的必要(比如从来没有用到)。可以参考以下几个方向:

  • 辅助分配:根据使用的场景,考虑放到哪个工具类里
  • 是否保留方法:可能会遇到从来没有用到过的方法(可以酌情移除)
  • 决策目标方法是不是通用工具方法:可能是业务需要,做的特殊处理,此时则不适合放到工具类当中。比如 ImageUtils#getImageUrlHeight 业务需要并非通用,在业务中处理更好。

重复方法做合并和统一(通过重载)

比如:FileUtils.deleteFile(File file) & FileUtils#deleteFile(File file, String[] excludeDir) 这两个函数的逻辑如果是各自处理的,可通过重载处理

使用 kotlin 的写法特性,通过指定参数默认值减少重载函数的数量

// 使用重载优化:
fun File.deleteAll():Boolean = deleteAll(null)
fun File.deleteAll(filter:FileFilter):Boolean{
  return false
}

// 使用 kotlin,设置参数默认值进一步优化
File.deleteAll(filter:FileFilter? = null):Boolean{
  return false
}

注意使用@JvmOverloads注解兼容 java 使用

上面的写法在 kotlin 中使用是没有问题,但是在 Java 文件中是无法调用 FileUtils.deleteAll() 的,必须要添加 filter 这个入参,可以通过 byteCode 看下

可以为方法添加注解@JvmOverloads 编译后会自动生成多个重载函数,如果不考虑 Java 的使用场景,可以不添加,需要的时候再补充也可以

kotlin 使用特性节制

kotlin 的特性很多,有些是可以简化写法,但不意味着强制这样使用,还是要考虑使用场景,比如

  • 为入参指定默认值,如果是常用的方法,可以将该重命名,然后使用内部函数(这样使用的时候会更直接,无需关注参数)
  • 扩展函数,可以扩展,但未必一定要去扩展,可考虑使用习惯