Middle
Koje obrasce dizajna možete koristiti u jeziku Kotlin?
sobes.tech АИ
Одговор од АИ
У Kotlin-у се често користе следећи образци:
- Singleton: Лако се реализује преко
object.object MySingleton { fun doSomething() { // ... } } - Factory Method: Апстрактна функција у суперкласу или интерфејсу коју реализују подкласе за креирање објеката.
interface Product { fun operation() } class ConcreteProductA : Product { override fun operation() { // ... } } abstract class Creator { abstract fun factoryMethod(): Product fun someOperation(): Product { val product = factoryMethod() // ... return product } } class ConcreteCreatorA : Creator() { override fun factoryMethod(): Product { return ConcreteProductA() } } - Abstract Factory: Група фабрика за креирање повезаних породица објеката.
interface AbstractProductA { fun usefulFunctionA() } interface AbstractProductB { fun usefulFunctionB() fun anotherUsefulFunctionB(collaborator: AbstractProductA) } interface AbstractFactory { fun createProductA(): AbstractProductA fun createProductB(): AbstractProductB } // Конкретне имплементације производа и фабрика... - Builder: Олакшава креирање сложених објеката корак по корак.
class Pizza private constructor( val crust: String, val sauce: String?, val toppings: List<String> ) { data class Builder( var crust: String = "thin", var sauce: String? = null, val toppings: MutableList<String> = mutableListOf() ) { fun withCrust(crust: String) = apply { this.crust = crust } fun withSauce(sauce: String) = apply { this.sauce = sauce } fun addTopping(topping: String) = apply { this.toppings.add(topping) } fun build() = Pizza(crust, sauce, toppings) } } fun main() { val pizza = Pizza.Builder() .withCrust("thick") .withSauce("tomato") .addTopping("pepperoni") .addTopping("mushrooms") .build() // ... use pizza } - Adapter: Омогућава објектима са несагласним интерфејсима да раде заједно.
open class Adaptee { fun specificOperation() { // ... } } interface Target { fun operation() } class Adapter(private val adaptee: Adaptee) : Target { override fun operation() { adaptee.specificOperation() } } - Decorator: Додаје нове функције постојећим објектима без измене њихове структуре. Расширења и делегирање у Kotlin-у ово веома олакшавају.
interface DataSource { fun readData(): String fun writeData(data: String) } class FileDataSource(private val filename: String) : DataSource { override fun readData(): String { // читање из фајла return "" } override fun writeData(data: String) { // запис у фајл } } class EncryptionDecorator(private val source: DataSource) : DataSource by source { override fun readData(): String { // дешифровати data val data = source.readData() return data // дешифровани подаци } override fun writeData(data: String) { // шифровати data source.writeData(data) // шифровани подаци } } - Observer: Одређује зависност "један према много". Coroutines Flow и Kotlin-ове делегиране својства могу се користити за имплементацију.
// Једноставна имплементација без Flow interface Observer { fun update(message: String) } class Subject { private val observers = mutableListOf<Observer>() fun attach(observer: Observer) { observers.add(observer) } fun detach(observer: Observer) { observers.remove(observer) } fun notifyObservers(message: String) { observers.forEach { it.update(message) } } } - Strategy: Одређује породицу алгоритама, инкапсулира сваки од њих и чини их међусобно заменљивим.
interface PaymentStrategy { fun pay(amount: Double) } class PayByCreditCard(private val cardNumber: String) : PaymentStrategy { override fun pay(amount: Double) { println("Плаћање $amount коришћењем кредитне картице $cardNumber") } } class PayByPayPal(private val email: String) : PaymentStrategy { override fun pay(amount: Double) { println("Плаћање $amount коришћењем PayPal-а $email") } } class Order(private val paymentStrategy: PaymentStrategy) { fun processOrder(amount: Double) { // ... нека обрада поруџбине paymentStrategy.pay(amount) } } - State: Омогућава објекту да мења своје понашање у зависности од унутрашњег стања. Sealed класе и when изрази ово поједностављују.
sealed class State { object Idle : State() object Loading : State() data class Error(val message: String) : State() data class Success(val data: Any) : State() } class Context { var state: State = State.Idle fun handleEvent() { when (state) { State.Idle -> { println("Обрада догађаја у стању Idle") state = State.Loading } State.Loading -> { println("Обрада догађаја у стању Loading, игнорисање.") } is State.Error -> { println("Обрада догађаја у стању Error: ${state.message}") // Могућност преласка у друго стање } is State.Success -> { println("Обрада догађаја у стању Success: ${state.data}") // Могућност преласка у друго стање } } } } - Repository: Апстрахује логику приступа подацима из пословне логике.
Многи други образци, као што су Facade, Proxy, Command, Iterator, Template Method и Visitor, такође су применљиви у Kotlin-у. Језичке особине Kotlin-а, као што су екстензије, делегирање, data класе и sealed класе, често чине имплементацију образаца идиоматичнијом и концизнијом.