Reflektioon perustuva validointi ja kuvaus
Rakentakaa yksinkertainen validaattori tai oliomuunnin annotaatioihin perustuvalla reflektiolla.
Reflektioon perustuva validointi ja kuvaus on ilmainen Kotlin Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Kotlin Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Mihin tätä mallia käytetään
Reflektioon perustuva validointi lukee annotaatiot luokan ominaisuuksista suorituksen aikana ja soveltaa validointisääntöjä automaattisesti — kenttiä ei tarvitse tarkistaa erikseen käsin. Sama tekniikka on ORM-muuntimien taustalla: ne muuntavat objekteja tietokantariveiksi ja päinvastoin.
Validate-annotaatio
Määritelkää ominaisuuksiin kohdistuva annotaatio, joka säilytetään suorituksen aikana:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Validate(
val minLength: Int = 0,
val maxLength: Int = Int.MAX_VALUE,
val pattern: String = ""
)Data-luokan annotointi
Soveltakaa @Validate-annotaatiota data-luokan ominaisuuksiin. Validaattori tarkistaa nämä suorituksen aikana:
data class UserForm(
@Validate(minLength = 2, maxLength = 50) val name: String,
@Validate(pattern = "^[\\w.]+@[\\w]+\\.[a-z]{2,}$") val email: String,
@Validate(minLength = 8) val password: String
)Validaattorifunktio
Käyttäkää KClass.declaredMemberProperties-ominaisuutta ominaisuuksien läpikäyntiin, annotaatioiden etsimiseen ja virheiden keräämiseen:
fun validate(obj: Any): List<String> {
val errors = mutableListOf<String>()
for (prop in obj::class.declaredMemberProperties) {
val ann = prop.findAnnotation<Validate>() ?: continue
val value = (prop as KProperty1<Any, *>).get(obj)?.toString() ?: ""
if (value.length < ann.minLength) errors += "${prop.name}: too short"
if (value.length > ann.maxLength) errors += "${prop.name}: too long"
if (ann.pattern.isNotEmpty() && !value.matches(Regex(ann.pattern)))
errors += "${prop.name}: invalid format"
}
return errors
}Validaattorin suorittaminen
Kutsukaa validate()-funktiota mille tahansa annotaatiolla merkitylle objektille. Funktio palauttaa virheviestien luettelon; tyhjä luettelo tarkoittaa, että objekti on kelvollinen:
val form = UserForm("A", "not-an-email", "short")
val errors = validate(form)
errors.forEach(::println)
// name: too short
// email: invalid format
// password: too shortObjektin muuntaminen Map-rakenteeksi @Column-annotaatiolla
Toinen reflektiomalli muuntaa objektin rakenteeksi Map käyttämällä @Column-annotaatiota sarakkeiden nimien ilmoittamiseen:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)
fun toMap(obj: Any): Map<String, Any?> =
obj::class.declaredMemberProperties
.mapNotNull { prop ->
val col = prop.findAnnotation<Column>() ?: return@mapNotNull null
col.name to (prop as KProperty1<Any, *>).get(obj)
}.toMap()Muuntimen käyttäminen
Annotoikaa data-luokka ja kutsukaa toMap()-funktiota saadaksenne sarakkeiden nimillä avaimet sisältävän kartan, joka on valmis INSERT-lauseketta varten:
data class User(
@Column("user_name") val name: String,
@Column("user_email") val email: String
)
val user = User("Alice", "alice@example.com")
println(toMap(user))
// {user_name=Alice, user_email=alice@example.com}Reflektion tulosten välimuistitus
Reflektioskannaukset ovat raskaita. Välimuistittakaa ominaisuuksien ja annotaatioiden välinen kuvaus käynnistyksen yhteydessä käyttämällä ConcurrentHashMap-rakennetta, jonka avaimina ovat KClass-arvot:
val cache = ConcurrentHashMap<KClass<*>, List<Pair<KProperty1<Any,*>, Column>>>()
fun columnsOf(klass: KClass<*>) = cache.getOrPut(klass) {
klass.declaredMemberProperties
.mapNotNull { p ->
p.findAnnotation<Column>()?.let { (p as KProperty1<Any,*>) to it }
}
}Validoinnin ja muuntamisen yhdistäminen
Voitte pinota useita annotaatioita yhdelle ominaisuudelle ja käsitellä kutakin itsenäisesti. Validoikaa ensin ja muuntakaa sen jälkeen — tai tehkää molemmat yhdellä läpikäynnillä keräämällä kunkin annotaatiotyypin tiedot:
data class Product(
@Validate(minLength = 1) @Column("product_name") val name: String,
@Column("price") val price: Double
)Rajoitukset
Reflektioon perustuva validointi on tehokasta, mutta siihen liittyy kompromisseja: se lisää suorituksenaikaista kuormitusta, riippuu annotaatioiden säilytyskäytännöstä eikä pysty havaitsemaan virheitä käännösaikana. Jos suorituskyky tai käännösaikainen turvallisuus on erityisen tärkeää, harkitkaa sen sijaan KSP:n avulla luotua koodia.
Milloin tätä mallia kannattaa käyttää
Reflektioon perustuva validointi on parhaimmillaan kehyskoodissa, jonka on käsiteltävä mielivaltaisia käyttäjän määrittämiä luokkia: ORM-järjestelmissä, serialisoijissa, lomakevalidaattoreissa ja asetusten sitojissa. Sovelluskoodissa, joka hallitsee omat tyyppinsä, kannattaa nopeuden ja selkeyden vuoksi suosia eksplisiittistä validointia.
Pikatarkistus
Mikä annotaation säilytyskäytäntö vaaditaan, jotta validointiannotaatio voidaan lukea suorituksen aikana?
Kertaus: reflektioon perustuva validointi ja muuntaminen
Tärkeimmät opit:
- Määritelkää ominaisuuksiin kohdistuvat annotaatiot, jotka säilytetään suorituksen aikana
- Käyttäkää
declaredMemberProperties- jafindAnnotation-toimintoja validoinnin tai muuntamisen ohjaamiseen - Välimuistittakaa tulokset
KClass-arvojen perusteella, jotta toistuvan reflektion aiheuttama kuormitus vältetään - Pinotkaa ominaisuudelle useita annotaatioita yhdistetyn toiminnan saavuttamiseksi
- Harkitkaa KSP:tä käännösaikaisena vaihtoehtona suorituskykyä vaativissa kohdissa
Opi Kotlin tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”Reflektioon perustuva validointi ja kuvaus” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Kotlin Academy-oppimispolun 3 oppituntia, myös oppitunnin “Reflektioon perustuva validointi ja kuvaus”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Reflektioon perustuva validointi ja kuvaus”?
Rakentakaa yksinkertainen validaattori tai oliomuunnin annotaatioihin perustuvalla reflektiolla. Harjoittelet Kotlin Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Kotlin Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Kotlin Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Reflektioon perustuva validointi ja kuvaus”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Kotlin Academy-oppitunnilla?
Kyllä. Jokainen Kotlin Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Kotlin-reflektio: KClass, KFunction, KProperty
- Mukautettujen annotaatioiden luominen ja kohdentaminen
- Annotaatioiden lukeminen ajon aikana
- Reflektioon perustuva validointi ja kuvaus