3.6局部函数和扩展

Kotlin提供了一个简洁的方案来减少重复代码:可以在函数中嵌套函数。这样既可以获得所需的结构,也无需额外的语法开销。
带重复代码的函数:

class User(val id: Int, val name: String, val address: String)
 fun saveUser(user: User) {
        if (user.name.isEmpty()) {
            throw IllegalArgumentException("用户名为空不能保存")
        }
        if (user.address.isEmpty()) {
            throw IllegalArgumentException("用户地址为空不能保存")
        }
        //保存user
    }

这里的重复代码是很少的,你可能不想要在类中一个面面俱到的方法中去验证用户的每一种特殊情况。但是,如果将验证代码放到局部函数中,可以摆脱重复,并保持清晰的代码结构,可以这样:

fun saveUser(user: User) {
        fun validate(user: User, value: String, fieldName: String) {
            if (value.isEmpty()) {
                throw IllegalArgumentException("用户$fieldName 为空不能保存")
            }
        }
        validate(user, user.name, "名")
        validate(user, user.address, "地址")
        //保存user
    }

这样不用重复验证逻辑,如果在项目演进时需要向User添加其他字段,也可以轻松添加更多验证。但是,把User对象传递给验证函数看起来还是有点难看。但是这完全不必要,因为局部函数可以访问所在函数中的所有参数和变量。可以利用这一点,去除冗余的User参数:

fun saveUser(user: User) {
        fun validate(value: String, fieldName: String) {
            if (value.isEmpty()) {
                throw IllegalArgumentException("用户$fieldName 为空不能保存")
            }
        }
        validate(user.name, "名")
        validate(user.address, "地址")
        //保存user
    }

也可以继续改进,把验证逻辑放到User类的扩展函数中:

fun User.validateBeforeSave() {
        fun validate(value: String, fieldName: String) {
            if (value.isEmpty()) {
                throw IllegalArgumentException("用户$fieldName 为空不能保存")
            }
        }
        validate(name, "名")
        validate(address, "地址")
    }

fun saveUser(user: User) {
        user.validateBeforeSave()
        //保存user
    }

将一段代码提取到扩展函数中,相当有效。如果能够遵循,类的api只能包含必须的方法,那么就可以让类保持精炼的同时,也让思路更清晰。另一方面,主要处理单个对象,而且不需要访问其私有数据的函数,可以访问它的成员而无需额外验证。

猜你喜欢

转载自blog.csdn.net/qq_26413249/article/details/80503001