Oi eu sou um novato no mundo Kotlin. Gosto do que vejo até agora e comecei a pensar em converter algumas de nossas bibliotecas que usamos em nosso aplicativo de Java para Kotlin.
Essas bibliotecas estão cheias de Pojos com setters, getters e classes Builder. Agora, pesquisei no Google qual a melhor maneira de implementar os Builders no Kotlin, mas sem sucesso.
2ª Atualização: A questão é como escrever um padrão de design do Builder para um simples pojo com alguns parâmetros no Kotlin? O código abaixo é minha tentativa de escrever código java e, em seguida, usar o eclipse-kotlin-plugin para converter em Kotlin.
class Car private constructor(builder:Car.Builder) {
var model:String? = null
var year:Int = 0
init {
this.model = builder.model
this.year = builder.year
}
companion object Builder {
var model:String? = null
private set
var year:Int = 0
private set
fun model(model:String):Builder {
this.model = model
return this
}
fun year(year:Int):Builder {
this.year = year
return this
}
fun build():Car {
val car = Car(this)
return car
}
}
}
design-patterns
kotlin
Keyhan
fonte
fonte
model
eyear
é mutável? Você os altera após umaCar
criação?Respostas:
Em primeiro lugar, na maioria dos casos, você não precisa usar construtores no Kotlin porque temos argumentos padrão e nomeados. Isso permite que você escreva
e use-o assim:
Se você absolutamente deseja usar construtores, veja como você pode fazê-lo:
Tornar o Builder um
companion object
não faz sentido porqueobject
s são singletons. Em vez disso, declare-a como uma classe aninhada (que é estática por padrão no Kotlin).Mova as propriedades para o construtor para que o objeto também possa ser instanciado da maneira regular (torne o construtor privado, se não for o caso) e use um construtor secundário que leve um construtor e delegue para o construtor principal. O código terá a seguinte aparência:
Uso:
val car = Car.Builder().model("X").build()
Esse código pode ser reduzido adicionalmente usando uma DSL do construtor :
Uso:
val car = Car.build { model = "X" }
Se alguns valores forem necessários e não tiverem valores padrão, você precisará colocá-los no construtor do construtor e também no
build
método que acabamos de definir:Uso:
val car = Car.build(required = "requiredValue") { model = "X" }
fonte
Car.Builder builder = new Car.Builder();
. No entanto, apenas a primeira versão possui uma interface fluente, portanto, as chamadas para a segunda e terceira versões não podem ser encadeadas.Uma abordagem é fazer algo como o seguinte:
Amostra de uso:
fonte
Como estou usando a biblioteca Jackson para analisar objetos do JSON, preciso ter um construtor vazio e não posso ter campos opcionais. Todos os campos também precisam ser mutáveis. Então eu posso usar essa sintaxe agradável, que faz a mesma coisa que o padrão Builder:
fonte
@JsonProperty
@JsonProperty
se compilar com a-parameters
opção.Eu pessoalmente nunca vi um construtor em Kotlin, mas talvez seja apenas eu.
Toda a validação necessária é realizada no
init
bloco:Aqui, tomei a liberdade de adivinhar que você realmente não queria
model
eyear
ser mutável. Além disso, esses valores padrão parecem não ter sentido (principalmentenull
paraname
), mas deixei um para fins de demonstração.Uma Opinião: O padrão do construtor usado em Java como um meio de viver sem parâmetros nomeados. Em linguagens com parâmetros nomeados (como Kotlin ou Python), é uma boa prática ter construtores com longas listas de parâmetros (talvez opcionais).
fonte
@JvmOverloads
kotlinlang.org/docs/reference/…Eu já vi muitos exemplos que declaram divertimentos extras como construtores. Eu pessoalmente gosto dessa abordagem. Economize esforço para escrever construtores.
Ainda não encontrei uma maneira que possa forçar a inicialização de alguns campos no DSL, como mostrar erros em vez de gerar exceções. Deixe-me saber se alguém souber.
fonte
Para uma classe simples, você não precisa de um construtor separado. Você pode usar argumentos opcionais do construtor, como Kirill Rakhman descreveu.
Se você possui uma classe mais complexa, o Kotlin fornece uma maneira de criar Builders / DSL no estilo Groovy:
Construtores com segurança de tipo
Aqui está um exemplo:
Exemplo do Github - Construtor / Montador
fonte
Hoje em dia, as pessoas devem verificar os construtores seguros para tipos da Kotlin .
O uso dessa maneira de criação de objetos será algo como isto:
Um bom exemplo de uso em ação é a estrutura vaadin-on-kotlin , que utiliza construtores typesafe para montar visões e componentes .
fonte
Estou atrasado para a festa. Eu também encontrei o mesmo dilema se tivesse que usar o padrão Builder no projeto. Mais tarde, depois da pesquisa, percebi que é absolutamente desnecessário, pois o Kotlin já fornece os argumentos nomeados e os argumentos padrão.
Se você realmente precisa implementar, a resposta de Kirill Rakhman é uma resposta sólida sobre como implementar da maneira mais eficaz. Outra coisa que você pode achar útil é que, em https://www.baeldung.com/kotlin-builder-pattern, você pode comparar e contrastar com Java e Kotlin em sua implementação
fonte
Eu diria que o padrão e a implementação permanecem praticamente os mesmos no Kotlin. Às vezes, você pode ignorá-lo graças aos valores padrão, mas, para criar objetos mais complicados, os construtores ainda são uma ferramenta útil que não pode ser omitida.
fonte
você pode usar o parâmetro opcional no exemplo do kotlin:
então
fonte
fonte
Implementei um padrão básico do Builder no Kotlin com o seguinte código:
E finalmente
Java:
Kotlin:
fonte
Eu estava trabalhando em um projeto Kotlin que expôs uma API consumida por clientes Java (que não pode tirar proveito das construções da linguagem Kotlin). Tivemos que adicionar construtores para torná-los utilizáveis em Java, então criei uma anotação do @Builder: https://github.com/ThinkingLogic/kotlin-builder-annotation - é basicamente um substituto para a anotação do Lombok @Builder para o Kotlin.
fonte