DIP: asoslar, bog‘liqlarni inversiyalash rivojlanishda

Muallif: IT Sectr Nashr etilgan: 2026-05-12 O'qish vaqti: 9 daq

DIP (Dependency Inversion Principle) — SOLID ning beshinchi prinsipi bo‘lib, modullar o‘rtasidagi bog‘liqliklarni qurish qoidalarini belgilaydi: yuqori darajadagi modullar pastki darajadagi modullarga bog‘liq bo‘lmasligi kerak, ikkalasi ham abstraksiyalarga bog‘liq bo‘lishi kerak. Abstraksiyalar tafsilotlarga bog‘liq bo‘lmasligi kerak — tafsilotlar abstraksiyalarga bog‘liq bo‘lishi kerak. Robert Martin tomonidan Clean Architecture (2017) da tasvirlangan bu prinsip, zaif bog‘langan arxitekturaning asosini tashkil qiladi. Ushbu kitob ma‘lumotlariga ko‘ra, bog‘liqliklarni inversiyalash prinsipi ilova qatlamlari o‘rtasidagi qattiq bog‘lanishlarni bartaraf etadi.

Asosiy

  • DIP — bog‘liqliklarni inversiyalash prinsipi, SOLID da beshinchi, arxitektura chegaralari haqida
  • Yuqori darajadagi modullar pastki darajadagi modullarni import qilmasligi kerak — faqat abstraksiyalar
  • DIP ≠ DI: Dependency Inversion — arxitektura prinsipi, Dependency Injection — uni amalga oshirish usuli
  • Abstraksiyalar yuqori darajadagi modulga, amalga oshirishlar esa pastki darajadagi modulga tegishli
  • DIP ko‘p qatlamli arxitekturalarda an‘anaviy bog‘liqlik iyerarxiyasini teskari aylantiradi

DIP (Dependency Inversion Principle) nima?

DIP (Dependency Inversion Principle) — bog‘liqliklarni inversiyalash prinsipi bo‘lib, modullar o‘rtasidagi bog‘liqliklarning yo‘nalishi haqidagi an‘anaviy tushunchani teskari aylantiradi. Yuqori darajadagi modullar (biznes mantiq) pastki darajadagi modullarga (ma‘lumotlar bazasi, tarmoq, UI) bevosita bog‘liq bo‘lmasligi kerak. Buning o‘rniga, ikkala daraja ham yuqori darajadagi modulda belgilanadigan abstraksiyalarga bog‘liq bo‘ladi.

DIP ning rasmiy ifodasi ikkita qoidani o‘z ichiga oladi: A — yuqori darajadagi modullar pastki darajadagi modullarga bog‘liq bo‘lmasligi kerak, ikkalasi ham abstraksiyalarga bog‘liq bo‘lishi kerak. B — abstraksiyalar tafsilotlarga bog‘liq bo‘lmasligi kerak, tafsilotlar abstraksiyalarga bog‘liq bo‘lishi kerak. Ikkinchi qoida birinchining natijasidir: agar abstraksiya tafsilotlarga bog‘liq bo‘lsa, u yuqori darajadagi modul uchun barqaror asos bo‘la olmaydi.

DIP siz odatdagi arxitektura shunday ko‘rinadi: BusinessLogic → DatabaseRepository — biznes mantiq bevosita aniq repozitoriydan bog‘liq. DIP bilan: BusinessLogic → DatabaseServiceInterface ← DatabaseRepository. BusinessLogic DatabaseRepository mavjudligidan xabardor emas, u faqat biznes mantiqdan tashqarida amalga oshiriladigan DatabaseService interfeysini biladi.

DIP da bog‘liqliklarning yo‘nalishi

Inversiya shuni anglatadiki, boshqaruv oqimi va bog‘liqlik oqimi qarama-qarshi yo‘nalishlarga qaratilgan. Boshqaruv oqimi yuqoridan pastga ketadi: UI → ViewModel → UseCase → Repository. Bog‘liqlik oqimi pastdan yuqoriga ketadi: Repository UseCase da belgilangan interfeysni amalga oshiradi. Repository (pastki daraja) UseCase ga (yuqori daraja) bog‘liq.

Bu inversiya DIP ni odatdagi qatlamlarga bo‘lishdan asosiy farqidir. An‘anaviy qatlamli arxitekturada har bir qatlam pastdagi qatlamga bog‘liq. DIP bilan arxitekturada barcha qatlamlar abstraksiyalarga bog‘liq va bu abstraksiyalarning amalga oshirilishi infratuzilma qatlamida joylashgan bo‘lib, DI mexanizmlari orqali yuqori qatlamlarga ulanadi.

Bog‘liqliklarni inversiyalash prinsipi qanday ishlaydi

DIP mexanizmi yuqori darajadagi modullarda abstraksiyalarni belgilash va ularni pastki darajadagi modullarda amalga oshirish orqali bajariladi. Yuqori darajadagi modul o‘ziga kerakli funksionallik uchun interfeys e‘lon qiladi. Pastki darajadagi modul bu interfeysni amalga oshiradi. Bog‘lash (wiring) ilovaning kompozitsiya ildizi darajasida sodir bo‘ladi.

Mavjud kodga DIP ni joriy qilish jarayoni: pastki darajadagi modul uchun interfeysni ajratib oling, bu interfeysni yuqori darajadagi modulga (yoki alohida abstraksiyalar qatlamiga) ko‘chiring, yuqori modulning bog‘liqligini interfeysga qayta yozing, pastki darajadagi modulni bu interfeysni amalga oshirishga majbur qiling. Ushbu qadamlardan so‘ng bog‘liqlik yo‘nalishi teskari tomonga o‘zgardi.

DIP kompozitsiya ildizi mexanizmini talab qiladi — ilovada barcha bog‘liqliklar yaratiladigan va bir-biriga bog‘lanadigan nuqta. Android da bu Application.get() yoki Hilt komponenti, iOS da — AppDelegate yoki SceneDelegate. Kompozitsiya ildizi kodning aniq amalga oshirishlar haqida biladigan yagona joyidir.

Qatlamlarni DIP orqali izolyatsiya qilish

DIP arxitektura chegaralarini shakllantiradi ilova qatlamlari o‘rtasida. ViewModel UserRepository interfeysiga bog‘liq bo‘lganda, presentation va domain qatlami o‘rtasida chegara paydo bo‘ladi: ViewModel (presentation) ma‘lumotlar qayerdan kelishini bilmaydi. Bu chegara UserRepository amalga oshirilishini (Room → REST → Mock) ViewModel ga ta‘sir qilmasdan o‘zgartirishga imkon beradi. Qancha ko‘p bunday chegaralar bo‘lsa, ilova framework va kutubxona o‘zgarishlariga shuncha chidamli bo‘ladi.

Google tomonidan tavsiya etilgan Android arxitekturasida DIP domain qatlamida joylashgan va Repository interfeyslariga bog‘liq bo‘lgan UseCase orqali amalga oshiriladi. RepositoryImpl data qatlamida joylashgan va bu interfeyslarni amalga oshiradi. Presentation qatlami (ViewModel) UseCase ga bog‘liq. Bog‘liqliklarning yo‘nalishi presentation dan domain ga, domain dan data ga ketadi — lekin hech qanday qatlam boshqa qatlamning aniq amalga oshirishlari haqida bilmaydi.

DIP va DI (Dependency Injection) o‘rtasidagi farq

DIP va DI ko‘pincha aralashtiriladi, ammo bu turli tushunchalar. DIP — arxitektura prinsipi (NIMA qilish kerak: abstraksiyalarga bog‘liq bo‘lish). DI — amalga oshirish namunasi (BUNI QANDAY qilish: bog‘liqliklarni konstruktor orqali uzatish). DIP modullar nimaga asoslanishi kerak? degan savolga, DI — obyektlar o‘z bog‘liqliklarini qanday oladi? degan savolga javob beradi.

Dependency Injection — bog‘liqliklarni obyektga konstruktor, metod yoki xususiyat orqali kiritish usuli. Kotlin sinfida Repository interfeysi konstruktor orqali uzatilganda — bu DI. ViewModel sinfining aniq RoomRepository amalga oshirilishidan emas, balki Repository interfeysiga bog‘liq bo‘lishi — bu DIP. DI — vosita, DIP — maqsad.

DIP ga DI frameworksiz rioya qilish mumkin: kompozitsiya ildizida bog‘liqliklarni qo‘lda bog‘lash ham DI dir (manual DI). DI framework (Dagger, Hilt, Koin) yordamida DIP ni buzish mumkin: agar ViewModel to‘g‘ridan-to‘g‘ri new() orqali Repository obyektini yaratsa — DIP buzilgan, hatto framework o‘rnatilgan bo‘lsa ham. DIP — arxitektura qarori, DI — texnik tafsilot.

Mobil rivojlanishda DIP misollari

Keling, Android misolini ko‘rib chiqaylik DIP ni ma‘lumotlar qatlamiga qo‘llash. DIP siz ViewModel to‘g‘ridan-to‘g‘ri RoomDatabase va DAO yaratadi. DIP bilan — ViewModel UserRepository interfeysiga bog‘liq, aniq RoomUserRepository amalga oshirilishi esa tashqaridan ta‘minlanadi.

kotlin
// Abstraksiya domain qatlamiga tegishli (yuqori daraja)
interface UserRepository {
    fun getUser(id: Int): User
}

// Domain qatlami faqat abstraksiyaga bog‘liq
class GetUserUseCase(
    private val repo: UserRepository
) {
    fun execute(id: Int): User = repo.getUser(id)
}

// Data qatlamidagi amalga oshirish domain qatlami abstraksiyasiga bog‘liq
class RoomUserRepository(
    private val dao: UserDao
) : UserRepository {
    override fun getUser(id: Int): User {
        return dao.getById(id)
    }
}

// Kompozitsiya ildizi
class AppModule {
    fun provideUserRepository(dao: UserDao): UserRepository {
        return RoomUserRepository(dao)
    }
}

iOS misoli Application Coordinator va navigatsiya uchun protokol bilan:

swift
// Navigatsiya abstraksiyasi domain qatlamida
protocol AuthNavigation {
    func navigateToHome()
    func navigateToLogin()
}

// ViewModel abstraksiyaga bog‘liq, UIKit ga emas
final class AuthViewModel {
    private let navigation: AuthNavigation

    init(navigation: AuthNavigation) {
        self.navigation = navigation
    }

    func onLoginSuccess() {
        navigation.navigateToHome()
    }
}

// Coordinator (UIKit qatlami) domain qatlami protokolini amalga oshiradi
final class AppCoordinator: AuthNavigation {
    func navigateToHome() {
        // UIKit navigatsiya kodi
    }
    func navigateToLogin() {
        // UIKit navigatsiya kodi
    }
}

Asosiy nuqta: AuthViewModel (domain) AppCoordinator (UIKit) mavjudligidan xabardor emas. U faqat AuthNavigation protokolini biladi. Agar ertaga UIKit SwiftUI bilan almashtirilsa — AuthViewModel o‘zgartirishni talab qilmaydi. DIP domain qatlamini frameworklar va UI kutubxonalaridan mustaqil qiladi.

DIP uchun vositalar: Dagger, Hilt, Koin

Hilt — Android uchun standart DI vositasi, Google tomonidan tavsiya etilgan. Jetpack ga kiritilgan, ViewModel, Fragment, Service va boshqa Android komponentlarini qo‘llab-quvvatlaydi. Hilt @Module, @Provides, @Inject annotatsiyalari orqali kompozitsiya ildizini yaratishni avtomatlashtiradi. Hilt dan foydalanish DIP ga rioya qilishni kafolatlamaydi — UserRepository interfeysi data qatlamida emas, domain qatlamida belgilanishi kerak.

Koin — kod yaratish va annotatsiya protsessorisiz Kotlin uchun yengil DI framework. Koin DSL (module, single, factory) o‘rganish osonroq, ammo bog‘liqliklarni tekshirish kompilatsiya vaqtida emas, runtime da sodir bo‘ladi. Koin iOS qo‘llab-quvvatlashi tufayli ko‘p platformali loyihalarda (KMP) mashhur.

Dagger 2 — Hilt ning oldingi versiyasi, katta loyihalarda hali ham qo‘llaniladi. Dagger kompilatsiya vaqtida DI kodini yaratadi, bu maksimal ishlash va qurish bosqichida xato diagnostikasini beradi. Hilt Dagger ustiga qurilgan va soddalashtirilgan API ni ta‘minlaydi. Yangi loyihalar uchun Google Hilt ni asosiy DI framework sifatida tavsiya qiladi.

DI modullarini qatlamlar bo‘yicha tashkil qilish

DI modullari arxitektura qatlamlariga mos kelishi va DomainModule, DataModule, PresentationModule ga bo‘linishi kerak. DomainModule faqat abstraksiyalar va UseCase ni ta‘minlaydi. DataModule abstraksiyalar uchun amalga oshirishlarni ta‘minlaydi. PresentationModule ViewModel ni UseCase bilan bog‘laydi. Bunday tashkil qilish domain qatlamining mustaqil qolishini kafolatlaydi.

DI frameworklari o‘rtasida migratsiya paytida (masalan, Koin dan Hilt ga) DomainModule strukturasi o‘zgarmaydi — faqat DataModule va PresentationModule da bog‘lash usullari o‘zgaradi. DIP domain mantig‘ining izolyatsiyasini ta‘minlaydi, DI framework esa texnik bog‘lash mexanizmidir.

Tez-tez so‘raladigan savollar

DIP har doim qo‘llanilishi kerakmi?

DIP arxitektura chegaralarida — ilova qatlamlari o‘rtasida (domain → data, presentation → domain) zarur. Bir qatlam ichida DIP ortiqcha bo‘lishi mumkin. Masalan, domain qatlami ichidagi StringFormatter yordamchi sinfi interfeysni talab qilmaydi — agar uni almashtirish uchun asos bo‘lmasa.

DIP bu bog‘liqliklarni kiritish bilan bir xilmi?

Yo‘q. DIP — prinsip: modullar abstraksiyalarga bog‘liq bo‘lishi kerak. DI — namuna: obyekt bog‘liqliklarni tashqaridan oladi, o‘zi yaratmaydi. DI — DIP ni amalga oshirish usuli, ammo DIP ga DI siz ham rioya qilish mumkin (fabrikalar yoki xizmat lokatori orqali). DI siz DIP mumkin, ammo arxitektura qiymati yo‘q.

DIP uchun interfeyslar qayerda belgilanishi kerak?

Interfeyslar undan foydalanadigan modulga tegishli, uni amalga oshiradigan modulga emas. UserRepository domain qatlamida e‘lon qilinadi, data qatlamida amalga oshiriladi. Bu DIP ning asosiy qoidasi: abstraksiyaning egasi iste‘molchi, amalga oshirish yetkazib beruvchi emas.

DIP testlashga qanday ta‘sir qiladi?

DIP testlashni mumkin qiladi izolyatsiya qilingan qatlamlarda. UserRepository (interfeys) ga bog‘liq bo‘lgan ViewModel ma‘lumotlar bazasisiz mock amalga oshirish bilan testlanadi. DIP siz ViewModel RoomUserRepository ga bog‘liq bo‘lardi va har bir test uchun ma‘lumotlar bazasi sozlamasini talab qilardi. DIP + DI test paytida modullarning to‘liq izolyatsiyasini ta‘minlaydi.

Android uchun qaysi DI framework ni tanlash kerak?

Hilt — Android loyihalari uchun standart tanlov, Google tomonidan tavsiya etilgan. Koin — Kotlin Multiplatform loyihalari uchun alternativ. Dagger 2 — mavjud loyihalar uchun, Hilt ga migratsiya asossiz bo‘lganda. Framework tanlovi arxitektura darajasida DIP ga rioya qilish zaruriyatini bekor qilmaydi.

Xulosa

  • DIP (Dependency Inversion Principle) — SOLID ning beshinchi prinsipi, abstraksiyalar orqali arxitektura chegaralari haqida
  • Yuqori darajadagi modullar pastki darajadagi modullarga bog‘liq emas — ikkalasi abstraksiyalarga bog‘liq
  • DIP ≠ DI: prinsipga qarshi amalga oshirish namunasi; DI — usul, DIP — maqsad
  • Abstraksiyalar iste‘molchiga tegishli (domain qatlami), yetkazib beruvchiga emas (data qatlami)
  • Kompozitsiya ildizi — ilovada aniq bog‘liqliklar to‘planadigan yagona joy
  • Hilt, Koin, Dagger — bog‘lashni avtomatlashtiradigan DI vositalari, ammo DIP arxitektura qarorini almashtirmaydi
  • Domain qatlami DIP ga muvofiq qurilganda frameworklar, UI va infratuzilma kutubxonalaridan mustaqil qoladi

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing