Cześć, jestem nowicjuszem w świecie Kotlin. Podoba mi się to, co widzę do tej pory i zacząłem myśleć o przekonwertowaniu niektórych naszych bibliotek, których używamy w naszej aplikacji, z Javy na Kotlin.
Te biblioteki są pełne Pojos z klasami ustawiającymi, pobierającymi i budującymi. Teraz szukałem w Google, aby znaleźć najlepszy sposób na wdrożenie Builders w Kotlinie, ale bez sukcesu.
Druga aktualizacja: Pytanie brzmi, jak napisać wzorzec projektowy Builder dla prostego pojo z niektórymi parametrami w Kotlin? Poniższy kod jest moją próbą napisania kodu java, a następnie użycia wtyczki eclipse-kotlin-plugin do konwersji na 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
źródło
źródło
model
iyear
być zmiennym? Czy zmieniasz je poCar
stworzeniu?Odpowiedzi:
Przede wszystkim w większości przypadków nie musisz używać konstruktorów w Kotlinie, ponieważ mamy domyślne i nazwane argumenty. To pozwala ci pisać
i używaj go tak:
Jeśli absolutnie chcesz korzystać z konstruktorów, oto jak możesz to zrobić:
Tworzenie Buildera
companion object
nie ma sensu, ponieważobject
są one singletonami. Zamiast tego zadeklaruj ją jako klasę zagnieżdżoną (która domyślnie jest statyczna w Kotlinie).Przenieś właściwości do konstruktora, aby można było również utworzyć wystąpienie obiektu w zwykły sposób (ustaw konstruktor jako prywatny, jeśli nie powinien) i użyj konstruktora pomocniczego, który pobiera konstruktora i delegatów do konstruktora podstawowego. Kod będzie wyglądał następująco:
Stosowanie:
val car = Car.Builder().model("X").build()
Ten kod można dodatkowo skrócić za pomocą konstruktora DSL :
Stosowanie:
val car = Car.build { model = "X" }
Jeśli jakieś wartości są wymagane i nie mają wartości domyślnych, musisz umieścić je w konstruktorze kreatora, a także w
build
metodzie, którą właśnie zdefiniowaliśmy:Stosowanie:
val car = Car.build(required = "requiredValue") { model = "X" }
źródło
Car.Builder builder = new Car.Builder();
. Jednak tylko pierwsza wersja ma płynny interfejs, więc nie można łączyć wywołań drugiej i trzeciej wersji.Jedną z metod jest wykonanie następujących czynności:
Próbka użycia:
źródło
Ponieważ używam biblioteki Jackson do analizowania obiektów z formatu JSON, potrzebuję pustego konstruktora i nie mogę mieć pól opcjonalnych. Również wszystkie pola muszą być zmienne. Następnie mogę użyć tej ładnej składni, która robi to samo, co wzorzec Builder:
źródło
@JsonProperty
@JsonProperty
, jeśli kompilujesz z-parameters
przełącznikiem.Osobiście nigdy nie widziałem budowniczego w Kotlinie, ale może to tylko ja.
Wszystkie potrzebne walidacje odbywają się w
init
bloku:Tutaj pozwoliłem sobie zgadnąć, że tak naprawdę nie chcesz
model
iyear
być zmiennym. Również te domyślne wartości wydają się nie mieć sensu (szczególnienull
dlaname
), ale zostawiłem jedną dla celów demonstracyjnych.Opinia: wzorzec konstruktora używany w Javie jako sposób na życie bez nazwanych parametrów. W językach z nazwanymi parametrami (jak Kotlin czy Python) dobrą praktyką jest posiadanie konstruktorów z długimi listami (być może opcjonalnych) parametrów.
źródło
@JvmOverloads
kotlinlang.org/docs/reference/ ...Widziałem wiele przykładów, które deklarują dodatkowe frajdy jako konstruktorzy. Osobiście podoba mi się to podejście. Oszczędzaj wysiłek pisania konstruktorów.
Nie znalazłem jeszcze sposobu, który mógłby wymusić zainicjowanie niektórych pól w DSL, na przykład pokazywanie błędów zamiast rzucania wyjątków. Daj mi znać, jeśli ktoś wie.
źródło
Do prostych zajęć nie potrzebujesz osobnego kreatora. Możesz skorzystać z opcjonalnych argumentów konstruktora, jak opisał Kirill Rakhman.
Jeśli masz bardziej złożoną klasę, Kotlin zapewnia sposób na tworzenie Groovy style Builders / DSL:
Twórcy bezpiecznych typów
Oto przykład:
Przykład Github - Builder / Assembler
źródło
W dzisiejszych czasach ludzie powinni sprawdzać konstruktorzy Kotlin z bezpiecznymi typami .
Użycie wspomnianego sposobu tworzenia obiektów będzie wyglądać mniej więcej tak:
Przyjemnym przykładem użycia „w akcji” jest framework vaadin-on-kotlin , który wykorzystuje bezpieczne kreatory do tworzenia widoków i komponentów .
źródło
Spóźniłem się na imprezę. Napotkałem też ten sam dylemat, gdybym musiał użyć wzorca Builder w projekcie. Później, po badaniach, zdałem sobie sprawę, że jest to absolutnie niepotrzebne, ponieważ Kotlin już dostarcza wymienione argumenty i argumenty domyślne.
Jeśli naprawdę musisz wdrożyć, odpowiedź Kirilla Rakhmana jest solidną odpowiedzią na temat tego, jak wdrożyć w najbardziej efektywny sposób. Inną rzeczą, która może Ci się przydać, jest https://www.baeldung.com/kotlin-builder-pattern, którą możesz porównać i porównać z Javą i Kotlinem w zakresie ich implementacji
źródło
Powiedziałbym, że wzór i implementacja pozostają prawie takie same w Kotlinie. Czasami można to pominąć dzięki wartościom domyślnym, ale w przypadku bardziej skomplikowanego tworzenia obiektów konstruktory są nadal przydatnym narzędziem, którego nie można pominąć.
źródło
możesz użyć opcjonalnego parametru w przykładzie kotlin:
następnie
źródło
źródło
Zaimplementowałem podstawowy wzorzec Builder w Kotlinie z następującym kodem:
I w końcu
Jawa:
Kotlin:
źródło
Pracowałem nad projektem Kotlin, który udostępnił API używane przez klientów Java (które nie mogą korzystać z konstrukcji języka Kotlin). Musieliśmy dodać konstruktory, aby były użyteczne w Javie, więc stworzyłem adnotację @Builder: https://github.com/ThinkingLogic/kotlin-builder-annotation - jest to w zasadzie zamiennik dla adnotacji Lombok @Builder dla Kotlin.
źródło