为了活动小家电-注解Annotation(七)

79 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的29天,点击查看活动详情

为了活动小家电,接着上篇搞!

app

在我们的应用模块中,我们想要使用注解。

build.gradle 文件如下所示。

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"

    defaultConfig {
        applicationId "com.april21dev.datavalidationkotlin"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation project(':test-annotation')
    kapt project(':test-processor')
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

因为需要用到注解,test-annotation 、 test-processor 设置为使用 kapt 处理。

下面是数据模型。

@DataValidation
data class Book(
    @MinLength(10, "长度最小 10")
    @MaxLength(50, "长度最大 50")
    val title: String,
    @MinValue(1, "书本价格最小值")
    @MaxValue(100000, "书本价格最大值")
    val price: Int,
    @MaxLength(10, "作者名字长度最大 10")
    val authorName: String,
    @Regex("^[\w!#$%&'*+/=?`{|}~^-]+(?:\.[\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}$", "邮箱正则")
    val authorEmail: String,
    @NotNull("字段可为空")
    @Nested
    val publisher: Publisher
)

@DataValidation
data class Publisher(
    @MaxLength(10, "出版社名字长度最大 10")
    val name: String
)

我只是创建了一个 Book 类和一个 Publisher 类,并对每个字段进行了注释。

之后,当您构建时,会自动在build下com.datavalidation.generated创建 DataValidationExtension.kt 文件。

Book 和 Publisher 的 validate() 函数写在 DataValidationExtension.kt 文件中。

fun Book.validate(): ValidationResult {
  val result = ValidationResult()
  
  if(title == null || title.length < 10) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("title", "长度最小 10"))
  }
  
  if(title == null || title.length > 50) {
    result.isValid = false
    result.invalidFieldNameAndTags.add(FieldNameTag("title", "长度最大 50"))
  }
  
  if(price == null || price.toLong() < 1) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("price", "书本价格最小值"))
  }
 
  if(price == null || price.toLong() > 100000) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("price", "书本价格最大值"))
  }
  
  if(authorName == null || authorName.length > 10) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("authorName", "作者名字长度最大 10"))
  }
  
  if(authorEmail == null ||
      !"^[\w!#${'$'}%&'*+/=?`{|}~^-]+(?:\.[\w!#${'$'}%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,6}${'$'}".toRegex().matches(authorEmail)) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("authorEmail", "邮箱正则"))
  }
  
  if(publisher == null) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("publisher", "字段可为空"))
  }
  
  if(publisher != null) {
    val nestedValidation = publisher.validate()
    if(!nestedValidation.isValid) {
      result.isValid = false
      result.invalidFieldNameTags.addAll(nestedValidation.invalidFieldNameTags)
    }
  }
  return result
}

fun Publisher.validate(): ValidationResult {
  val result = ValidationResult()
  
  if(name == null || name.length > 10) {
    result.isValid = false
    result.invalidFieldNameTags.add(FieldNameTag("name", "出版社名字长度最大 10"))
  }
  return result
}

下面是使用实际 validate() 函数和结果的示例。

val book = Book("随便", 0, "名字", "mingzi@163/com",Publisher("随便随便随便随便随便随便 --- 反正超过10个"))

val validationResult = book.validate()

到目前为止,我已经简单地创建了通过注解来判断数据模型有效性的逻辑。

除此之外,我认为如果你使用注解,你可以通过简单地实现你想要的各种功能而不需要样板代码来提高生产力。

谢谢你的阅读。