en dataklasse er et koncept, der ikke er bundet til noget specifikt programmeringssprog, det er et mønster, der er praktisk nok for de fleste programmører som en enkel måde at repræsentere, indkapsle og flytte information rundt.

en dataklasse refererer til en klasse, der kun indeholder felter og rå metoder til at få adgang til dem (getters og setters). Disse er simpelthen containere til data, der bruges af andre klasser. Disse klasser indeholder ingen yderligere funktionalitet og kan ikke uafhængigt fungere på de data, de ejer.

normalt repræsenterer dataklasser enheder i den virkelige verden, og det er almindeligt at have snesevis eller hundreder af disse klasser i et projekt, hvilket betyder, at oprettelse, ændring og manipulation af disse objekter det er en meget almindelig opgave for en udvikler.

en Dataklasse i Java

Sådan ser en dataklasse normalt ud i Java:

du vil bemærke, at vi er altoverskyggende toString() , equals() og hashCode() metoder (erklæret i Object.java klassen ). Hvorfor er altoverskyggende disse metoder relevante i dataklasser?

når vi implementerer disse tre metoder, skaber vi værdiobjekter, klasser, for hvilke to tilfælde med passende lige feltværdier betragtes som udskiftelige. (Bemærk: For at være helt sandt, skal vi gøre klassen uforanderlig. At gøre felterne endelige og fjerne setterne hjælper. Uforanderlighed betragtes ofte som en god praksis og anbefales, når det er muligt)

  • equals() : som standard returnerer true bare hvis de to variabler henviser til det samme objekt, dvs.hvis positionen i hukommelsen er den samme. Vi tilsidesætter denne metode til returnering true, hvis objekterne indeholder de samme oplysninger, med andre ord, hvis objekterne repræsenterer den samme enhed. Det kontrollerer egenskaberne er de samme, og de indeholder den samme værdi.
  • hashCode() : som standard returnerer objektets hukommelsesadresse i heksadecimal. Det er en numerisk værdi at identificere et objekt under ligestillingstestning, dvs.lige objekter har den samme hash-kode. Denne metode skal tilsidesættes, når toString() tilsidesættes, så den returnerer en hash-kode beregnet ud fra egenskabernes værdier.
  • toString(): Som standard returnerer objekttypen og hashCode(), for eksempel [email protected]+ . Vi tilsidesætter denne metode for at have en mere menneskelig læsbar version af objektet som User(name=Steve, surname=Jobs) .

på trods af at det er et så vigtigt koncept, er der intet i Java-koden ovenfor, der gør denne klasse anderledes end nogen anden. Programmører kan genkende det som en dataklasse på grund af klassestrukturen og mønstrene, men fra kompilatorsynspunktet er denne klasse bare en anden klasse.

oprettelse af dataklasser er så almindeligt, at udviklere ofte bruger IDE og andre plugins til at hjælpe dem med denne gentagne opgave. Smerten ved at oprette en dataklasse i Java kan lindres af plugins eller IDE, men de fleste fejl introduceres ved yderligere ændringer af disse klasser. Det er meget let at glemme at ændre alle ledsagermetoderne i overensstemmelse hermed, hver gang et felt fjernes eller tilføjes.

en dataklasse i Java mangler sprogunderstøttelse. Det er en gentagen og bug-udsat opgave, der repræsenterer for meget friktion for et moderne programmeringssprog.

en dataklasse i Kotlin

den samme dataklasse i Kotlin ville se sådan ud:

data class User(var name: String, var age: Int)

Kotlin hæver dataklasser til førsteklasses borgere, der introducerer nøgleordet data. Lad os bryde det ned.

  • Getters og settere

getters og settere oprettes automatisk i Kotlin, når vi erklærer egenskaber. Kort sagt, hvad var name: String betyder er, atUser klassen har en ejendom, der er offentlig (standard synlighed i Kotlin), mutabel (var) og er en String type. Da det er offentligt, skaber det getter, og da det er foranderligt, skaber det setter.

hvis vi ønsker at gøre klassen skrivebeskyttet (ingen settere), skal vi bruge val :

data class User(val name: String, val age: Int)

vi kan blande val og var i samme klassedeklaration. Du kan tænke på val som en final variabel i Java.

alt forklaret hidtil, det er almindeligt for enhver klassedeklaration i Kotlin, men nøgleordet data er, hvad der gør en forskel her.

  • datanøgleordet

at erklære en klasse som en dataklasse får os implementeret toString(), hashCode() og equals() automatisk på samme måde som vi beskrev ovenfor for Java-klassen. Så hvis vi opretter en brugerklasse som User("Steve Jobs",56) og kalder toString() – metoden, får vi noget som:User(name=Steve Jobs, age=56).

Destruktureringserklæringer

nøgleordet data indeholder funktioner, der tillader destruktureringserklæringer. Kort sagt, det skaber en funktion for hver ejendom, så vi kan gøre ting som dette:

kopifunktion

nøgleordet data giver os en praktisk måde at kopiere klasser på, der ændrer værdien af nogle egenskaber. Hvis vi vil oprette en kopi af en bruger, der ændrer alderen, er det sådan, vi ville gøre det:

egenskaber, der er angivet i klasselegemet, ignoreres

kompilatoren bruger kun de egenskaber, der er defineret inde i den primære konstruktør til de automatisk genererede funktioner.

egenskaben address det vil ikke blive behandlet af nøgleordet data, så det betyder, at de automatisk genererede implementeringer vil ignorere det.

par og tredobbelt

Pair og Triple er standard dataklasser i biblioteket, men Kotin-dokumenterne fraråder selv brugen af dem til fordel for mere læsbare og skræddersyede dataklasser.

krav og begrænsninger

  • en dataklassekonstruktør skal have mindst en parameter.
  • alle parametre skal være marked som val eller var.
  • en dataklasse kan ikke være abstract, open, sealed eller inner.
  • equals , toString og hashCode metoder kan udtrykkeligt tilsidesættes.
  • eksplicitte implementeringer for componentN() og copy() funktioner er ikke tilladt.
  • at udlede en dataklasse fra en type med en copy() funktionsmatchende signatur blev udskrevet i Kotlin 1.2 og var forbudt i Kotlin 1.3.
  • a data klasse kan ikke strække sig fra en anden data klasse.
  • a data klasse kan udvide andre klasser (siden Kotlin 1.1)

dataklasser er førsteklasses borgere i Kotlin. I en meget kort syntaks tilbyder de en friktionsløs løsning med alle fordele og ingen kompromiser.

hvad betyder det for Android

jeg vil forsøge at forklare, hvad der er de vigtigste fordele, som jeg har fundet ved hjælp af Kotlin dataklasser i mine Android-projekter. Disse er ikke alle af dem og er måske ikke de vigtigste, men disse er de mest åbenlyse fra min erfaring indtil videre.

  • datamodeller

arkitektur i Android var (og er stadig) et varmt emne. Der er flere muligheder, men de fleste af dem har til fælles adskillelse af bekymringer og principper for enkelt ansvar. Ren arkitektur – meget berømt i Android-samfundet-er et sæt god praksis, der skal følges, når man sigter mod en god arkitektur, der lægger vægt på at bruge forskellige modeller til forskellige lag af arkitekturen. Dette betyder, at et projekt med 3 eller 4 forskellige datamodeller bliver standard.

hvad det betyder er, at antallet af dataklasser i et projekt er meget højt, og operationer som oprette, læse, ændre, kopiere, sammenligne, kortlægge… datamodelklasser er daglige opgaver, der drager fordel af Kotin Data Class auto-genereret kode. Sparer en enorm mængde tid og reducerer mulighederne for at introducere fejl.

  • ikke mere Auto-værdi

brug af værdityper er en god praksis, der er meget udvidet i Android, især blandt dataklasser.

en værditype er et objekt fra en uforanderlig værdiklasse.
en værdiklasse er en klasse, for hvilken lighed afhænger af dens indhold.
en uforanderlig klasse er en klasse, der ikke kan ændres efter oprettelsen.

AutoValue er et populært bibliotek fra Google, der hjælper os med at skabe værdityper. Det gør sit job, men det er meget verbose for noget, der ikke burde være så kompliceret.

brug af kotlin data klasser med val adgangsmodifikator giver os en tæt nok tilnærmelse til værdityper.

data class User(val name : String, val age : Int)

den forrige Brugerklasse er en klasse, der er tæt nok på værdityper, i en meget kortere syntaks. For en god del af mennesker kan AutoValue erstattes af Kotlin. Mindre kode, ingen annotationsbehandling og et bibliotek mindre at afhænge af.

Bemærk: Kotlin tilbyder skrivebeskyttede egenskaber og klasser med nøgleordet val. Skrivebeskyttet og uforanderlig er ikke den samme (mere her), men generelt betragtes som god nok til praktiske formål.

  • ikke mere Lombok

en af måderne udviklere forsøgte at spare tid, når de beskæftiger sig med dataklasser, bruger biblioteker til at generere getter-og setter-metoder. Lombok er en af de (i)berømte i Android / Java. Det kræver ikke kun biblioteket, men også et plugin til AS. Den lange historie kort er for de fleste udviklere Lombok bringe så mange fordele som hovedpine, så det bliver det Bibliotek, du begynder at elske, men efter et stykke tid kan du ikke vente med at slippe af med, men du gør det aldrig, fordi det er overalt.

da Kotlin-dataklasser ikke kræver manuelt at skrive getter/setter-metoder, er hovedbehovet for Lombok væk.

  • Genbrugsvisning DiffUtil

Genanvendelsesvisning i Android er kontrollen. Det er i hver app i flere skærme. En vigtig komponent ved implementering af Genbrugsvisningsadaptere er DiffUtil-klassen. DiffUtil beregner diff mellem to lister for at sende ændringerne-hvis nogen – til adapteren. Det er meget mere effektivt end at opdatere hele listen igen og igen, og det animerer ændringerne smukt.

DiffUtil er stærkt afhængig af varernes lighed, hvilket betyder, at to elementer er de samme, når deres indhold er det samme. Hver gang du bruger en Genbrugsvisning, skal du bruge DiffUtil, hvilket betyder, at du har brug for en måde at sammenligne, hvis to objekter indeholder de samme oplysninger. Dette er en af grundene til, at vi skal tilsidesætte equals i Vores Java-dataklasser, men med Kotlin data klasser kommer det gratis.

Bemærk: Hvis du ikke er bekendt med DiffUtil tjek denne hurtig start guide.

  • test

i testklasser kontrollerer vi konstant, om de forventede værdier svarer til de faktiske værdier. Sammenligning af objekter lighed (som beskrevet før) er en meget almindelig opgave.

selvom du ikke behøver at tilsidesætte equals, toString og toHash triplet for dig regelmæssig app runtime, er chancerne for, at du bliver nødt til at tilsidesætte disse metoder til testformål, høje, så Kotlin-dataklasser rydder vejen til test uden undskyldninger.

Addendum

lad os tale om nogle andre almindelige scenarier, der er værd at nævne, når vi arbejder med Kotlin-dataklasser. Dette er ikke strengt relateret til dataklasser, men er især almindeligt blandt dem.

  • flere konstruktører
data class User(val name : String, val age : Int)

i klassen User vi definerede tidligere, skal vi eksplicit angive name og age, når vi opretter en forekomst som User("Steve", 56) .

i Kotlin kan vi definere standardværdier for argumenter på en sådan måde, at hvis vi ikke videregiver en værdi for det argument, tildeles standardværdien den.

data class User(val name : String, val age :Int = 0)

User("Steve", 56) er stadig gyldig, men nu er en anden konstruktør User("Steve") tilladt. I så fald vil værdien age være 0.

vi kan tildele standardværdier til begge parametre, der tillader en tredje konstruktør User() hvor name vil være tom og age vil være 0.

data class User(val name : String = "", val age : Int = 0)

så nu User(), User("Steve") og User("Steve",56) alle er gyldige opkald.

dette har nogle begrænsninger: valgfrie parametre skal være sidste parametre i konstruktøren. Den næste vil ikke kompilere.

data class User(val name : String = "", val age : Int)
val user = User(56) // This doesn't compile

en anden begrænsning er, at hvis vi har flere valgfrie parametre, skal de springes over fra højre til venstre.

data class User(
val name : String,
val surname : String = "",
val age : Int = 0
)User("Steve")
User("Steve", "Jobs")
User("Steve", "Jobs", 56)
User("Steve",56) // This wont compile

for at håndtere disse begrænsninger tilbyder Kotlin Navngivne argumenter. Dette giver os mulighed for at specificere, hvilket argument der hører til hver værdi. Nu kan vi gøre ting somUser(name = "Steve", age = 56) — eller kortere User("Steve", age = 56) – hvor efternavnet tildeles standardværdien.

Standardargumenter og Navngivne argumenter er en meget praktisk måde at tilbyde flere konstruktører og overbelastninger fra en meget kompakt erklæring.

  • @JvmOverloads

alt forklaret i det foregående punkt tager ikke hensyn til opkald fra Java-siden. Kotlin er interoperabel med Java, så vi skal kunne oprette forekomster af User klassen fra Java.

hvis du ikke vil bruge det fra Java, så er du færdig, men ellers skal du bruge @JvmOverloads annotationen, da Java ikke tilbyder Navngivne argumenter.

data class User @JvmOverloads constructor(
val name : String,
val surname : String = "",
val age : Int = 0
)

hvad dette gør genererer flere konstruktører, så det kan kaldes fra Java.

Bemærk: Det er vigtigt at bemærke, at det ikke vil skabe enhver mulig permutation, men dem, der følger af at fjerne de valgfrie argumenter fra højre til venstre. Mere her

  • Builders

givet Kotlin tilbyder navngivne parametre og standardargumenter, gør det det mindre sandsynligt behovet for bygherrer. Derudover viser moderne IDE ‘ er som Android Studio allerede navnet på parameteren på opkaldssiden, hvilket gør det lettere at læse, hvilket gør det mindre interessant bare til læsbarhedsformål.

i de tilfælde, hvor bygherremønsteret stadig er nødvendigt. Kotlin tilbyder ikke noget særligt for at hjælpe os med det. Et builder mønster i Kotlin ligner:

  • Kommentarer

det er meget almindeligt, at nogle datamodelklasser bruger annotationsbehandling. For eksempel er API-modeller (dataklasser, der repræsenterer deserialiserede svar fra API ‘ en) ofte kommenteret med Gson-eller Moshi-kommentarer. Persistensmodellerne (dataklasser til at repræsentere data gemt i lokal lagring/databaser) er ofte kommenteret med rum-eller Realm-annoteringer.

i Kotlin kan vi stadig bruge disse kommentarer. For eksempel, Dette er en Brugermodel, der skal gemmes i Rumdatabasen:

Resume

Kotlin dataklasser er resultatet af mange års læring af smerte og frustration med dataklasser i Java. De sigter mod at have alle fordelene og ingen af ulemperne. Brug af dem er meget enkelt og behageligt, og når du først er vant til det, er det meget svært at se tilbage.

i Android hjælper de os på forskellige måder, men for det meste sparer de meget tid og reducerer fejl.

en Kotlin-dataklasse er et godt eksempel på, hvad Kotlin er som programmeringssprog: kortfattet, pragmatisk og en glæde for udviklere.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.

lg