Uma classe de dados é um conceito que não vinculado a nenhuma linguagem de programação específica, é um padrão que é conveniente o suficiente para a maioria dos programadores como uma maneira simples de representar, encapsular e mover a informação.

uma classe de dados refere-se a uma classe que contém apenas campos e métodos crud para acessá-los (getters e setters). Trata-se simplesmente de contentores para dados utilizados por outras classes. Estas classes não contêm nenhuma funcionalidade adicional e não podem operar de forma independente com os dados que possuem.

geralmente, as classes de dados representam entidades do mundo real, e é comum ter dezenas ou centenas dessas classes em um projeto, o que significa que criar, modificar e manipular esses objetos é uma tarefa muito comum para um desenvolvedor.

a Data class in Java

This is how a data class usually looks in Java:

você vai notar que estamos ultrapassando os métodos toString() , equals() e hashCode() (declarado na classe Object.java). Por que razão é que a sobreposição destes métodos é relevante nas classes de dados?Ao implementar esses três métodos criamos objetos de valor, classes para as quais quaisquer duas instâncias com valores de campo adequadamente iguais são consideradas permutáveis. (Nota: para ser completamente verdade, precisamos tornar a classe imutável. Tornar os campos finais e remover os setters ajuda. A imutabilidade é muitas vezes considerada uma boa prática e recomendada quando possível)

  • equals() : por padrão, Retorna true apenas se as duas variáveis se referem ao mesmo objeto, ou seja, se a posição na memória é a mesma. Devemos sobrescrever esse método para retornar true se os objetos contêm a mesma informação, em outras palavras, se os objetos representam a mesma entidade. Verifica que as propriedades são as mesmas e que contêm o mesmo valor.
  • hashCode() : por padrão, Retorna o endereço de memória do objeto em hexadecimal. É um valor numérico para identificar um objeto durante o teste de igualdade, ou seja, objetos iguais têm o mesmo código de hash. Este método deve ser substituído quando toString() é substituído de modo que ele retorna um código de hash calculado a partir dos valores das propriedades.
  • toString(): Por padrão Retorna o tipo de objeto e o hashCode(), por exemplo [email protected]+ . Nós sobrepomos este método para ter uma versão mais legível pelo homem do objeto como User(name=Steve, surname=Jobs) .

apesar de ser um conceito tão importante, não há nada no código Java acima que torne esta classe diferente de qualquer outra. Programadores podem reconhecê-lo como uma classe de dados por causa da estrutura de classe e padrões, mas do ponto de vista do compilador, esta classe é apenas outra classe.

criar classes de dados é tão comum que os desenvolvedores muitas vezes usam o IDE e outros plugins para ajudá-los com esta tarefa repetitiva. A dor de criar uma classe de dados em Java pode ser aliviada por plugins ou pela IDE, mas a maioria dos bugs são introduzidos em novas modificações dessas classes. É muito fácil esquecer de modificar todos os métodos companheiros de acordo cada vez que um campo é removido ou adicionado.

uma classe de dados em Java carece de suporte de linguagem. É uma tarefa repetitiva e propensa a erros que representa muita fricção para uma linguagem de programação moderna.

Uma classe de dados em Kotlin

A mesma classe de dados em Kotlin seria algo parecido com isto:

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

Kotlin eleva dados de classes para a primeira classe de cidadãos, introduzindo o data palavra-chave. Vamos desmontá-lo.

  • Getters and setters

the getters and setters are created automatically in Kotlin when we declare properties. Em resumo, o que var name: String significa é que a classe User tem uma propriedade que é pública (visibilidade padrão em Kotlin), mutável (var) e é um tipo String. Dado que é público, cria o getter, e dado que é mutável, cria o setter.

Se queremos que a classe só de leitura (não setters), precisamos usar val :

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

podemos misturar val e var na mesma declaração de classe. Você pode pensar em val como uma variável final em Java.

tudo explicado até agora, é comum a qualquer declaração de classe em Kotlin, mas a palavra-chave data é o que está fazendo a diferença aqui.

  • O data palavra-chave

Declarar uma classe como uma classe de dados é gonna get us implementado toString() , hashCode() e equals() automaticamente, da mesma forma que descrito acima para a classe de Java. Então se criarmos uma classe de usuário como User("Steve Jobs",56) e chamarmos o método toString() teremos algo como:User(name=Steve Jobs, age=56).

declarações de destruição

a palavra-chave data fornece funções que permitem declarações de destruição. Em suma, cria uma função para cada propriedade para que possamos fazer coisas como esta:

Copy function

the data keyword gives us a handy way of copying classes changing the value of some properties. Se queremos criar uma cópia de um usuário de alterar a idade, esta é a forma de fazê-lo:

Propriedades declaradas no corpo da classe são ignorados

O compilador usa apenas as propriedades definidas dentro o principal construtor para o gerado automaticamente funções.

a propriedade address não vai ser tratada pela palavra-chave data, por isso significa que as implementações auto-geradas Irão ignorá-la.

Pair e Triple

Pair e Triple são classes de dados padrão na biblioteca, mas os próprios documentos do Kotin desencorajam o uso deles em favor de classes de dados mais legíveis e personalizadas.

requisitos e limitações

  • um construtor de classes de dados precisa de ter pelo menos um parâmetro.
  • todos os parâmetros devem ser comercializados como val ou var.
  • Uma classe de dados não pode ser abstract, open, sealed ou inner .
  • equals , toString e os métodos hashCode podem ser explicitamente sobrepostos.Não são permitidas implementações explícitas para funções componentN() e copy().
  • derivar uma classe de dados de um tipo com uma assinatura de correspondência de função copy() foi depreciada em Kotlin 1.2 e foi proibida em Kotlin 1.3.
  • a data a classe não pode estender-se a partir de outra classe data.
  • a data a classe pode alargar outras classes (uma vez que Kotlin 1.1)

As classes de dados são cidadãos de primeira classe em Kotlin. Em uma sintaxe muito curta eles oferecem uma solução sem fricção com todas as vantagens e sem compromissos.

What does it mean for Android

i’m gonna try to explain what are the main advantages that i’ve found using Kotlin data classes in my Android projects. Estes não são todos eles e podem não ser os mais importantes, mas estes são os mais óbvios da minha experiência até agora.

  • modelos de Dados

Arquitetura do Android foi (e ainda é) um tema quente. Existem múltiplas opções, mas a maioria delas têm em comum a separação de preocupações e princípios de responsabilidade única. Arquitetura limpa-muito famosa na Comunidade Android-é um conjunto de boas práticas a seguir quando se pretende uma boa arquitetura que coloca ênfase no uso de diferentes modelos para diferentes camadas da arquitetura. Isto significa que um projeto com 3 ou 4 modelos de dados diferentes se tornam padrão.

o que isso significa é que o número de classes de dados em um projeto é muito alto, e operações como criar, ler, modificar, copiar, comparar, map… classes de modelos de dados são tarefas diárias que se beneficiam do Código auto-gerado da classe de dados Kotin. Economiza uma grande quantidade de tempo e reduz as oportunidades de introduzir bugs.

  • No more Auto-Value

Using value types is a good practice very extended in Android, especially among data classes.

um tipo de valor é um objeto de uma classe de valor imutável.
uma classe de valor é uma classe para a qual a igualdade depende de seu conteúdo.
uma classe imutável é uma classe que não pode ser modificada após a criação.

AutoValue é uma biblioteca popular do Google que nos ajuda a criar tipos de valor. Faz o seu trabalho, mas é muito verboso para algo que não devia ser tão complicado.

usando as classes kotlin data com o modificador de acesso val dá-nos uma aproximação suficientemente próxima dos tipos de valor.

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

a classe de utilizador anterior é uma classe suficientemente próxima dos tipos de valor, numa sintaxe muito mais Curta. Para um bom grupo de pessoas, AutoValue pode ser substituído por Kotlin. Menos código, sem processamento de anotações, e uma biblioteca a menos para depender.Nota: Kotlin oferece propriedades e classes apenas para leitura com a palavra-chave val. Somente leitura e imutável não é o mesmo (mais aqui), mas em geral, é considerado bom o suficiente para propósitos práticos.

  • No more Lombok

uma das maneiras que os desenvolvedores tentaram economizar tempo ao lidar com classes de dados é usando bibliotecas para gerar métodos getter e setter. Lombok é um dos (in)famosos em Android/Java. Ele requer não só a biblioteca, mas também um plugin para AS. O resumo de longa história é para a maioria dos desenvolvedores Lombok trazer tantas vantagens como dores de cabeça, então torna-se que a biblioteca que você começa a amar, mas depois de um tempo, você não pode esperar para se livrar, mas você nunca faz porque está em toda parte.

dado que as Classes de dados do Kotlin não necessitam de escrever manualmente os métodos getter / setter, a principal necessidade de Lombok desapareceu.

  • RecyclerView DiffUtil

RecyclerView in Android is the widget. Está em todas as aplicações em vários ecrãs. Um componente importante na implementação de adaptadores Reciclerview é a classe DiffUtil. DiffUtil calcula a diferença entre duas listas a fim de enviar as alterações-se houver – para o adaptador. É muito mais eficiente do que refrescando toda a lista vezes sem conta, e anima as mudanças lindamente.

DiffUtil depende fortemente da igualdade dos itens, o que significa que dois itens são os mesmos quando seu conteúdo é o mesmo. Cada vez que você usa um RecyclerView, você deve estar usando DiffUtil, o que significa que você precisa de uma maneira de comparar se dois objetos contêm a mesma informação. Esta é uma das razões pelas quais precisamos sobrepor equals em nossas classes de dados Java, mas com as classes Kotlin data ele vem de graça.Nota: Se não estiver familiarizado com DiffUtil verifique este guia de arranque rápido.

  • ensaios

nas classes de ensaio, estamos constantemente a verificar se os valores esperados correspondem aos valores reais. Comparar a igualdade de objetos (como descrito antes) é uma tarefa muito comum.

mesmo que não necessite de sobrepor o tripleto equals , toString e toHash para o seu tempo de execução regular do aplicativo, as chances de que você vai precisar sobrepor esses métodos para fins de teste são altas, de modo que as classes de dados de Kotlin limpar o caminho para o teste sem desculpas.

Addendum

Let’s talk about some other common scenarios worth mentioning when working with Kotlin data classes. Isto não está estritamente relacionado com classes de dados, mas são especialmente comuns entre eles.

  • Vários construtores
data class User(val name : String, val age : Int)

No User classe definimos anteriormente, precisamos especificar explicitamente o name e age quando criar uma instância como o User("Steve", 56) .

Em Kotlin, podemos definir valores padrão para argumentos de tal forma que, em caso de não passar um valor para o argumento, o valor padrão é atribuído a ele.

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

User("Steve", 56) ainda é válido, mas agora é permitido um segundo construtor User("Steve"). Nesse caso, o valor age será 0.

podemos atribuir valores padrão a ambos os parâmetros permitindo um terceiro construtor User() onde o name estará vazio e o age será 0.

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

so now User(), User("Steve") and User("Steve",56) all are valid calls.

isto tem algumas limitações: os parâmetros opcionais precisam ser os últimos parâmetros no construtor. O próximo não vai compilar.

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

outra limitação é que se temos vários parâmetros opcionais, eles têm que ser ignorados da direita para a esquerda.

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

para lidar com estas limitações Kotlin oferece argumentos nomeados. Isso nos permite especificar a que argumento pertence a cada valor. Agora podemos fazer coisas comoUser(name = "Steve", age = 56) — ou menor User("Steve", age = 56) – onde o sobrenome será atribuído ao valor padrão.

argumentos predefinidos e argumentos nomeados são uma forma muito útil de oferecer múltiplos construtores e cargas a partir de uma declaração muito compacta.

  • @JvmOverloads

all explained in the previous point is not taking into consideration calls from the Java side. O Kotlin é interoperável com o Java, por isso precisamos ser capazes de criar instâncias da classe User a partir do Java.

se você não vai usá-lo a partir de Java, então você está feito, mas caso contrário, você vai precisar da anotação @JvmOverloads dado que Java não oferece argumentos nomeados.

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

o que isso está fazendo gerando vários construtores para que ele possa ser chamado a partir de Java.

nota: é importante notar que não vai criar todas as permutações possíveis, mas as resultantes da remoção dos argumentos opcionais da direita para a esquerda. More here

  • Builders

Given Kotlin offers named parameters and default arguments, it makes it less less likely the need for builders. Além disso, IDEs modernos como o Android Studio já mostram o nome do parâmetro no lado chamador, tornando mais fácil de ler tornando-o menos interessante apenas para fins de legibilidade.

nos casos em que o padrão construtor ainda é necessário. O Kotlin não oferece nada de especial para nos ajudar. Um padrão de construtor no Kotlin parece:

  • anotações

é muito comum para algumas classes de modelos de dados usar o processamento de anotações. Por exemplo, modelos API (classes de dados para representar respostas deserializadas da API) são muitas vezes anotados com anotações Gson ou Moshi. Os modelos de persistência (classes de dados para representar dados armazenados em armazenamento local/bases de dados) são muitas vezes anotados com anotações de sala ou Reino.

em Kotlin ainda podemos usar essas anotações. Por exemplo, Este é um modelo de usuário a ser armazenado na Base de dados do quarto:

resumo

as classes de dados de Kotlin são o resultado de anos de aprendizagem da dor e frustração com as classes de dados em Java. Eles pretendem ter todas as vantagens e nenhuma das desvantagens. Usá-los é muito simples e agradável e uma vez que você se acostumar com isso, é muito difícil olhar para trás.

em Android, eles nos ajudam de maneiras diferentes, mas principalmente eles economizam muito tempo e reduzem bugs.

uma classe de dados de Kotlin é um bom exemplo do que Kotlin é como uma linguagem de programação: concisa, pragmática e uma alegria para os desenvolvedores.

Deixe uma resposta

O seu endereço de email não será publicado.

lg