Creationele ontwerppatronen in Kotlin: Builder

1. Inleiding

In dit korte artikel zullen we zien hoe u het Builder Design Pattern in Kotlin implementeert.

2. Bouwerpatroon

Het Builder-patroon is het patroon dat mensen vaak gebruiken, maar zelden zelf creëren.

Het is geweldig om het bouwen van objecten af ​​te handelen die veel parameters kunnen bevatten en wanneer we het object onveranderlijk willen maken als we klaar zijn met het construeren ervan.

Bekijk hier onze tutorial over Creational Design Patterns voor meer informatie.

3. Implementatie

Kotlin biedt veel handige functies, zoals benoemde en standaardparameters, van toepassing zijn() en dataklasse waardoor het gebruik van klassieke Builder-patroonimplementatie wordt vermeden.

Om die reden zullen we eerst een klassieke implementatie in Java-stijl zien en vervolgens een korte vorm in Kotlin-stijl.

3.1. Implementatie in Java-stijl

Laten we beginnen met het maken van één klas - Voedselbestelling - die alleen-lezen velden bevat, omdat we niet willen dat externe objecten er rechtstreeks toegang toe hebben:

class FoodOrder private constructor (builder: FoodOrder.Builder) {val bread: String? val specerijen: String? val vlees: String? val fish: String? init {this.bread = builder.bread this.condiments = builder.condiments this.meat = builder.meat this.fish = builder.fish} class Builder {// builder code}}

Let erop dat de constructor is privaat zodat alleen de geneste Bouwer klasse heeft er toegang toe.

Laten we nu verder gaan met het maken van de geneste klasse die zal worden gebruikt om objecten te bouwen:

class Builder {var bread: String? = null private set var condiments: String? = null private set var meat: String? = null private set var fish: String? = null privé set leuk brood (brood: String) = pas {this.bread = brood} leuke specerijen toe (specerijen: String) = pas {this.condiments = specerijen} leuk vlees toe (vlees: String) = pas {this.meat = toe meat} fun fish (fish: String) = pas {this.fish = fish} fun build () = FoodOrder (this)} toe 

Zoals we zien, onze Bouwer heeft dezelfde velden als de buitenste klasse. Voor elk buitenste veld hebben we een bijpassende setter-methode.

In het geval dat we een of meer verplichte velden hebben, in plaats van setter-methoden te gebruiken, laten we ze door een constructor laten instellen.

Merk op dat we de van toepassing zijn functie om de vloeiende ontwerpaanpak te ondersteunen.

Eindelijk, met de bouwen methode noemen we de Voedselbestelling constructeur.

3.2. Implementatie in Kotlin-stijl

Om ten volle te profiteren van Kotlin, moeten we enkele best practices die we in Java gewend zijn opnieuw bekijken. Velen van hen kunnen worden vervangen door betere alternatieven.

Laten we eens kijken hoe we idiomatische Kotlin-code kunnen schrijven:

class FoodOrder private constructor (val bread: String ?, val condiments: String ?, val meat: String ?, val fish: String?) {data class Builder (var bread: String? = null, var condiments: String? = null, var meat: String? = null, var fish: String? = null) {leuk brood (brood: String) = pas {this.bread = brood} leuke specerijen toe (specerijen: String) = pas {this.condiments = specerijen} plezier toe vlees (vlees: String) = pas {this.meat = vlees} leuke vis (vis: String) = pas toe {this.fish = vis} fun build () = FoodOrder (brood, specerijen, vlees, vis)}}

Kotlin wordt geleverd met benoemde en standaardparameters om het aantal overbelastingen te minimaliseren en de leesbaarheid van de functie-aanroep verbeteren.

We kunnen ook profiteren van de dataklassenstructuur van Kotlin, die we hier in een andere tutorial verder onderzoeken.

Ten slotte, evenals in implementatie in Java-stijl, van toepassing zijn() is handig voor het implementeren van vloeiende setters.

4. Gebruiksvoorbeeld

Laten we in het kort eens kijken hoe we kunnen bouwen Voedselbestelling objecten die deze Builder-patroonimplementatie gebruiken:

val foodOrder = FoodOrder.Builder () .bread ("wit brood") .vlees ("spek"). kruiderijen ("olijfolie") .build () 

5. Conclusie

Het Builder-patroon lost een veel voorkomend probleem op bij het objectgeoriënteerd programmeren van hoe flexibel een onveranderlijk object kan worden gemaakt zonder veel constructors te schrijven.

Bij het overwegen van een aannemer, moeten we ons concentreren op de vraag of de constructie al dan niet complex is. Als we te eenvoudige constructiepatronen hebben, kan de inspanning om ons flexibele bouwobject te maken veel groter zijn dan het voordeel.

Zoals altijd is de code beschikbaar op Github.