Sobes.tech
Middle

Կարող եք բացատրել Kotlin- ում դասի մեջ դելեգատի աշխատանքի սկզբունքը:

sobes.tech AI

Պատասխան AI-ից

Կոտլինում դելեգատը օբյեկտ է, որը ստանձնում է որոշակի առաջադրանքի կատարմանը կամ դելեգատում է մեթոդների կանչերը մյուս օբյեկտին:

Հիմնական օգտագործման սցենարներ՝

  1. Հատկանիշների դելեգատ (Delegated Properties): Հանձնարարել կառավարման getter-ների և setter-ների փոխանցումը այլ օբյեկտին:

    • lazy: Հատկանիշի արժեքի հաշվարկը առաջին մուտքի ժամանակ:
    • observable: Գործողության կատարմամբ փոփոխության ժամանակ:
    • vetoable: Պայմանների հիման վրա փոփոխության արգելք:
    class Example {
        // Հաշվարկվում է միայն առաջին մուտքի ժամանակ
        val lazyValue: String by lazy {
            println("Հաշվարկում եմ!")
            "Բարև"
        }
    
        // Կոչվում է յուրաքանչյուր փոփոխության ժամանակ
        var name: String by Delegates.observable("<չկա անուն>") { prop, old, new ->
            println("Անունը փոխվեց $old-ից $new-ին")
        }
    }
    
  2. Ինտերֆեյսների դելեգատ (Class Delegation): Ինտերֆեյսի իրականացմանը՝ մեթոդների կանչերը ուղղորդելով մյուս օբյեկտին:

    interface Base {
        fun print()
    }
    
    class BaseImpl(val x: Int) : Base {
        override fun print() {
            println(x)
        }
    }
    
    // Իրականացնում է Base, դելեգատելով BaseImpl-ին
    class Derived(b: Base) : Base by b
    
    fun main() {
        val b = BaseImpl(10)
        Derived(b).print() // Տպում է 10
    }
    
  3. Ֆունկցիաների դելեգատ (Function Delegation): Չնայած որ առանձին ֆունկցիաների դելեգատացման հատուկ սինտաքս չկա, ինչպես հատկությունների կամ ինտերֆեյսների համար, դա հիմնականում իրականացվում է կոմպոզիցիայի և այլ օբյեկտների մեթոդների կանչով:

Ինչպես է աշխատում հատկությունների դելեգատը՝

Կոտլինի կոմպիլյատորը գեներացնում է օգնական կոդ։ Դելեգատին վերապահված հատկության համար, կոմպիլյատորը գեներացնում է թաքնված հատկություն և կանչում getValue և setValue մեթոդները (փոփոխական հատկությունների համար) delegate օբյեկտում՝ փոխանցելով անհրաժեշտ կոնտեքստը (դասի օրինակ, հատկության մետադատան):

// Պսևդոկոդի օրինակ՝ ինչպես է կոմպիլյատորը մշակել՝ val p: String by delegate
/*
private val _p: Delegate<Any?, String> = delegate_initializer
val p: String
    get() = _p.getValue(this, ::p) // Կոչ `getValue`-ին դելեգատում
*/

Դելեգատային օբյեկտը պետք է ունենա համապատասխան մեթոդներ՝

  • getValue(thisRef, property: KProperty<*>): T հատկության համար T տիպի։ thisRef դասի օրինակ է, property - հատկության մետադատան։
  • setValue(thisRef, property: KProperty<*>, value: T) փոփոխական հատկության համար։

Առավելությունները՝

  • Կոդի կրկնակի օգտագործում: Ընդհանուր տրամաբանությունը (սաստիկ ինիցիալիզացիա, փոփոխությունների հետևում) փոխանցվում է առանձին դելեգատին և բազմակի օգտագործվում:
  • Կոդի ընթերցելիության բարելավում: Կոդը ավելի փոքր է, բոյլեռպլեյթ կոդը թաքնված է դելեգատում:
  • Մոդուլայնություն: Հատկանիշների կառավարման կամ ինտերֆեյսների իրականացման տրամաբանությունը առանձնացվում է հիմնական դասի տրամաբանությունից։