SOLID: tamoyillar, 5 OOP qoidalari va ishlanmada qo'llash

Muallif: IT Sectr Nashr etilgan: 2026-05-11 O'qish vaqti: 10 daq

SOLID — Robert C. Martin (Uncle Bob) tomonidan 2000-yillarning boshida ishlab chiqilgan beshta ob'ektga yo'naltirilgan dasturlash tamoyili. DigitalOcean, 2024 ma'lumotlariga ko'ra, SOLID Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation va Dependency Inversion deb ochiladi. Bu tamoyillar Clean Architecture asosini tashkil etadi va Android (MVP, MVVM, Clean Architecture) va iOS (VIPER, TCA) ishlanmasida qo'llaniladi.

Asosiy

  • SOLID — moslashuvchan va barqaror kod yaratish uchun Robert C. Martin tomonidan ishlab chiqilgan besh OOP tamoyilining akronimi: SRP, OCP, LSP, ISP, DIP.
  • SRP (Single Responsibility) — har bir sinf o'zgartirish uchun bitta sababga ega, modul uchun bitta mas'uliyat.
  • OCP (Open-Closed) — sinflar kengaytirish uchun ochiq, o'zgartirish uchun yopiq, meros va polimorfizm orqali amalga oshiriladi.
  • LSP (Liskov Substitution) — kichik sinflarning obyektlari dasturning to'g'riligini o'zgartirmasdan asosiy sinf obyektlarini almashtirishi kerak.
  • ISP (Interface Segregation) — mijozlar foydalanmaydigan interfeyslarga bog'liq bo'lmasligi kerak, interfeyslar tor va spesifik bo'lishi kerak.
  • DIP (Dependency Inversion) — yuqori darajadagi modullar pastki darajadagi modullarga bog'liq emas, ikkalasi ham abstraksiyalarga bog'liq.

SOLID nima? Besh tamoyilga umumiy nazar

SOLID — beshta ob'ektga yo'naltirilgan dizayn tamoyilini bildiruvchi mnemonic akronim. Atama Robert C. Martin tomonidan “Design Principles and Design Patterns” (2000) maqolasida kiritilgan va keyinchalik “Agile Software Development: Principles, Patterns, and Practices” (2002) kitobida ommalashtirilgan. SOLID framework yoki kutubxona emas — kodni kamroq bog'liq, ko'proq test qilinadigan va o'zgartirish uchun qulayroq qiladigan amaliyotlar to'plami.

Clean Coder Blog, 2014 ma'lumotlariga ko'ra, har bir SOLID tamoyili ma'lum bir dizayn muammosini hal qiladi: SRP God-sinflar bilan kurashadi, OCP — kaskad o'zgarishlar bilan, LSP — noto'g'ri meros bilan, ISP — semiz interfeyslar bilan, DIP — qattiq bog'lanish bilan. Birgalikda ular MVP, MVVM va MVI bilan Android loyihalarida ishlatiladigan Clean Architecture asosini tashkil qiladi.

SRP: Single Responsibility Principle

Single Responsibility Principle (SRP) — yagona mas'uliyat tamoyili. Formula: “Sinf o'zgartirish uchun faqat bitta sababga ega bo'lishi kerak.” Bu har bir modul yoki sinf aniq bir funksionallik yoki domen obyekti uchun javobgar degani. Agar sinf ham foydalanuvchilarni, ham email jo'natishni boshqarsa — uning o'zgartirish uchun ikkita sababi bor, bu SRPni buzadi.

Robert C. Martin, 2002 ga ko'ra, SRP eng muhim va shu bilan birga eng ko'p buziladigan tamoyildir. Mobil ishlanmada SRP ko'pincha Activity/Fragment da UI mantig'i, navigatsiya, tarmoq ishi va biznes mantig'ini birlashtirib buziladi. Yechim — har bir qatlamni alohida sinfga ajratish: UI mantig'i uchun ViewModel, ma'lumotlar uchun Repository, navigatsiya uchun NavController.

SRP misoli: UserManager bo'linishi

UserManager sinfini ko'rib chiqaylik, u profilni yuklaydi, sozlamalarni saqlaydi va email jo'natadi. Bu uch xil mas'uliyat, har biri alohida sinfga ajratilishi kerak: UserProfileRepository (yuklash), UserSettingsStorage (saqlash) va EmailService (jo'natish). Mijoz kodi (ViewModel) uchalasini Dependency Injection orqali ishlatadi va har bir sinf alohida osonlik bilan test qilinadi va boshqalarga ta'sir qilmasdan o'zgartiriladi.

kotlin
// ❌ SRP buzilishi: Activity tarmoq, BD va UI haqida biladi
class ProfileActivity : AppCompatActivity() {
    fun loadProfile() {
        api.getUser() // Tarmoq chaqiruvi
        db.saveUser()    // BD bilan ishlash
        updateUI()         // UI yangilanishi
    }
}

// ✅ SRP bajarilgan: qatlamlar ajratilgan
class ProfileViewModel : ViewModel() {
    private val repo = UserRepository()
    fun loadProfile() { repo.getUser() }
}

SRP buzilish belgilari: sinf 200 dan ortiq satrni o'z ichiga oladi, turli sohalardan metodlari bor, tez-tez turli sabablarga ko'ra o'zgaradi. Android ishlanmasi uchun qoida oddiy: Activity faqat ekranning hayot aylanishi uchun javobgar, ViewModel — UI holati uchun, Repository — ma'lumot manbalari uchun.

SRP va mikroservis arxitekturasi

SRP tamoyili nafaqat sinflarga, balki xizmat darajasidagi arxitekturaga ham tegishli. Har bir mikroservis bir domen obyekti uchun javobgar: UserService — faqat foydalanuvchilar, PaymentService — faqat to'lovlar, NotificationService — faqat bildirishnomalar. Bu xizmatlarni mustaqil ravishda masshtablash, joylashtirish va test qilish imkonini beradi. Mobil ilovada mikroservis darajasida SRP API mijozlarining domenlar bo'yicha bo'linishida namoyon bo'ladi.

OCP: Open-Closed Principle

Open-Closed Principle (OCP) — ochiqlik/yopiqlik tamoyili. Sinflar kengaytirish uchun ochiq (yangi xatti-harakat qo'shilishi mumkin) va o'zgartirish uchun yopiq (mavjud kod o'zgarmaydi) bo'lishi kerak. Bunga polimorfizm, abstrakt sinflar va interfeyslar orqali erishiladi. Mavjud metodga if-else qo'shish o'rniga, interfeysning yangi implementatsiyasi yaratiladi.

Clean Coder Blog, 2014 ga ko'ra, OCP Strategy naqshi bilan birgalikda eng samarali hisoblanadi. Masalan, ilova turli to'lov usullarini (Google Pay, Apple Pay, PayPal) qo'llab-quvvatlasa, to'lov protsessoriga switch-case qo'shish shart emas. Har bir to'lov usuli umumiy PaymentGateway interfeysini implementatsiya qiladi va yangi to'lov tizimi mavjud kodni o'zgartirmasdan yangi sinf sifatida qo'shiladi.

kotlin
// ✅ OCP: kengaytirishga ochiq, o'zgartirishga yopiq
interface PaymentGateway {
    fun processPayment(amount: Double): Boolean
}

class GooglePayGateway : PaymentGateway {
    override fun processPayment(amount: Double) = true
}

// Yangi to'lov tizimi — mavjud kodni o'zgartirmasdan
class ApplePayGateway : PaymentGateway {
    override fun processPayment(amount: Double) = true
}

LSP: Liskov Substitution Principle

Liskov Substitution Principle (LSP) — Barbara Liskovning almashtirish tamoyili. Agar S T ning kichik turi bo'lsa, T obyektlarini dastur xususiyatlarini o'zgartirmasdan S obyektlari bilan almashtirish mumkin. Rasmiy ravishda: asosiy sinfdan foydalanadigan funksiya uning istalgan kichik sinfi bilan to'g'ri ishlashi kerak. Agar kichik sinf asosiy sinf tashlamaydigan joyda exception tashlasa — LSP buzilgan.

Robert C. Martin, 2002 ga ko'ra, LSP SOLIDning tushunish eng qiyin tamoyilidir. Buzilishning klassik misoli — Rectangle (to'rtburchak) dan meros olgan Square sinfi (kvadrat). Agar Square uchun setWidth ham enini, ham balandligini o'rnatsa, Rectangle xatti-harakatini kutayotgan mijoz kodi kutilmagan natija oladi. Mobil ishlanmada LSP ko'pincha ViewModel meros olishda buziladi, bunda bola ViewModel majburiy bog'liqliklarni qo'shadi.

kotlin
// ❌ LSP buzilishi: Square Rectangle xatti-harakatini buzadi
open class Rectangle(open var width: Int, open var height: Int)

class Square(side: Int) : Rectangle(side, side) {
    override var width
        get() = super.width
        set(value) { super.setBoth(value, value) }
}

ISP: Interface Segregation Principle

Interface Segregation Principle (ISP) — interfeyslarni ajratish tamoyili. Mijozlar foydalanmaydigan interfeyslarga bog'liq bo'lmasligi kerak. Bitta “semiz” interfeys o'rniga bir nechta tor, ixtisoslashtirilgan interfeyslar yaratiladi. Agar sinf interfeysni implementatsiya qilsa, lekin metodlarning bir qismi UnsupportedOperationException tashlasa yoki bo'sh qolsa — bu ISP buzilishining aniq belgisidir.

DigitalOcean, 2024 ga ko'ra, ISP mobil ishlanmada ViewModel va Repository dizaynida ayniqsa dolzarbdir. Barcha CRUD metodlari bilan bitta UserRepository interfeysi o'rniga QueryUserRepository (faqat o'qish) va CommandUserRepository (yozish) yaratish yaxshiroq. U holda o'quvchi mijoz (UI elementi) faqat Query interfeysiga bog'liq va yozish metodlari haqida bilmaydi.

kotlin
// ❌ Semiz interfeys — mijoz keraksiz metodlarni implementatsiya qilishga majbur
interface UserOperations {
    fun getUser(id: String): User
    fun saveUser(user: User)
    fun deleteUser(id: String)
    fun exportUsers(): File
}

// ✅ ISP: ajratilgan interfeyslar
interface UserReader { fun getUser(id: String): User }
interface UserWriter { fun saveUser(user: User) }
interface UserDeleter { fun deleteUser(id: String) }

DIP: Dependency Inversion Principle

Dependency Inversion Principle (DIP) — bog'liqliklarni teskari qilish tamoyili. Yuqori darajadagi modullar pastki darajadagi modullarga bog'liq bo'lmasligi kerak. Ikkala daraja ham abstraksiyalarga (interfeyslarga) bog'liq bo'lishi kerak. Abstraksiyalar tafsilotlarga bog'liq bo'lmasligi kerak — tafsilotlar abstraksiyalarga bog'liq. Bu “Dependency Injection” (bog'liqliklarni kiritish) bilan bir xil emas, garchi DI DIPni implementatsiya qilishning keng tarqalgan usuli bo'lsa ham.

Robert C. Martin, 2019 ga ko'ra, DIP Clean Architecture asosidir. ViewModel (yuqori daraja) to'g'ridan-to'g'ri RetrofitApi (tafsilot) namunasini yaratmasligi kerak. Buning o'rniga ViewModel UserRepository interfeysiga bog'liq va Retrofit bilan aniq UserRepositoryImpl implementatsiyasi konstruktor orqali uzatiladi. Android-da DIP Hilt/Dagger yoki Koin orqali implementatsiya qilinadi: barcha bog'liqliklar DI konteyneri orqali ta'minlanadi.

kotlin
// ✅ DIP: Modul abstraksiyaga bog'liq, tafsilotga emas
class UserRepositoryImpl(
    private val api: UserApi,   // Interfeysga bog'liq
    private val db: UserDao     // Interfeysga bog'liq
) : UserRepository {

    override suspend fun getUser(id: String): User {
        return api.fetchUser(id)
    }
}

// Hilt DI: tafsilotlar DI moduli orqali bog'lanadi
@Module
object NetworkModule {
    @Provides
    fun provideUserApi(retrofit: Retrofit): UserApi =
        retrofit.create(UserApi::class.java)
}

SOLID-ni mobil ishlanmada qo'llash

Mobil ishlanmada SOLID barcha darajalarda qo'llaniladi: ilova arxitekturasidan tortib alohida sinflargacha. Android loyihalarida Clean Architecture kodni uch qatlamga ajratadi: domain (biznes mantig'i — frameworklardan mustaqil), data (repositorylar, API, BD) va presentation (UI, ViewModel). Domain qatlami SOLID tamoyillaridan foydalanadi: use case (SRP), repository interfeyslari (DIP), entity sinflari (OCP + LSP).

Android Developers Guide, 2025 ga ko'ra, SRP Android-da ViewModel, Repository va Mapper bo'linishida namoyon bo'ladi. OCP — DataSource interfeysi orqali yangi ma'lumot manbalari qo'shganda. LSP — turli repositorylardan Result ni bir xil ishlashda. ISP — CQRS yondashuvida (Read/Write repositorylarini ajratish). DIP — bog'liqliklarni kiritish uchun Hilt/Koin orqali.

TamoyilUsiz muammoMobil loyihada yechim
SRP1000+ sartr ActivityViewModel + UseCase + Repository
OCPTo'lov turiga qarab switch-caseStrategy: PaymentGateway interfeysi
LSPBaseViewModel almashtirishda xatoKichik sinflar shartnomasini tekshirish
ISPUnsupportedOperationExceptionReader / Writer ajratish
DIPViewModel qo'lda Retrofit yaratadiHilt / Koin DI konteyneri

SOLID qo'llashdagi odatiy xatolar

SOLID xatolari ko'pincha kodni haddan tashqari murakkablashtirish bilan bog'liq. Birinchisi — kontekstni hisobga olmasdan tamoyillarga so'zma-so'z amal qilish. Bitta UserService sinfini “toza” ISP uchun 10 interfeys va 15 sinfga bo'lish overengineering. SOLID vosita, maqsad emas. Ikkinchi xato — SRPni “bitta metod = bitta mas'uliyat” bilan aralashtirish. Sinf bir nechta metodga ega bo'lishi mumkin, agar ularning barchasi bitta mas'uliyat sohasiga tegishli bo'lsa.

Simple Thread, 2024 ga ko'ra, uchinchi xato — Android-da ViewModel meros olishda LSPni e'tiborsiz qoldirish. Agar asosiy ViewModel LiveData kutsa, bola esa StateFlow ishlatsa — LiveData-ga obuna bo'lgan mijoz kodi yangilanishlarni olmaydi. To'rtinchi — testlash uchun DIPni buzish: RepositoryImpl to'g'ridan-to'g'ri OkHttpClient namunasini yaratadi, bu birlik testlarini imkonsiz qiladi.

Oltin o'rta qoidasi: SOLIDni real muammoni hal qilganda qo'llang (tez-tez o'zgarishlar, testlash qiyinligi, takrorlanish). Oddiy CRUD ekranlari uchun barcha besh tamoyilga qat'iy rioya qilish ortiqcha. Biznes mantig'i, moliyaviy hisob-kitoblar va API o'zaro aloqalari uchun SOLID majburiydir.

SOLID va Clean Architecture aloqasi

Clean Architecture (Robert C. Martin, 2012) — SOLIDni ilova qatlamlari darajasida to'g'ridan-to'g'ri qo'llash. SRP use case chegaralarini belgilaydi (har bir use case — bitta sinf). OCP repository interfeyslari orqali amalga oshiriladi (Data qatlami Domainni o'zgartirmasdan o'zgarishi mumkin). ISP Use Case ni kirish/chiqish boundary ga bo'lishni ta'minlaydi. DIP — bog'liqliklarning Domain qatlami ichkarisiga yo'nalishi. LSP repositoryning har qanday implementatsiyasi use case ni buzmasdan almashtirilishini kafolatlaydi.

Ko'p beriladigan savollar

SOLID oddiy so'zlar bilan nima?

SOLID — kodni o'zgartirish, testlash va tushunish oson bo'lishi uchun beshta yozish qoidasi. Har bir harf bitta tamoyil: katta sinflar yozmang (SRP), mavjud kodni o'zgartirmang — yangisini qo'shing (OCP), merosxo'rlarning xatti-harakatini buzmang (LSP) va boshqalar.

Qaysi SOLID tamoyili eng muhim?

SRP (Single Responsibility) eng muhim hisoblanadi, chunki uning buzilishi God-sinflarga — testlash va o'zgartirish qiyin bo'lgan ulkan sinflarga olib keladi. Biroq DIP (Dependency Inversion) bo'lmasa, kod qattiq bog'liq bo'lib qoladi, bu ham juda muhim.

SOLID mobil ishlanma uchun majburiymi?

Majburiy emas, lekin uzoq hayot aylanishiga ega tijorat loyihalari uchun juda tavsiya etiladi. Oddiy ilovalar (bitta ekran, biznes mantig'i yo'q) uchun SOLID ortiqcha bo'lishi mumkin. 50+ ekran va 3+ dasturchi bo'lgan loyihalar uchun SOLID zaruriy minimumdir.

SOLIDga rioya qilinmasa nima bo'ladi?

Natijalar: sinflar “semiz” bo'ladi (1000+ satr), bir joydagi o'zgarish uchta boshqa joyni buzadi, birlik testlarini yozish imkonsiz bo'ladi, yangi funksiya qo'shish kunlar o'rniga haftalar oladi. Vaqt o'tishi bilan kod “Big Ball of Mud” — chalkash va mo'rt narsaga aylanadi.

Loyihada SOLIDga rioya qilinayotganini qanday tekshirish mumkin?

Rioya qilish belgilari: har bir sinf 200 satrdan kam, funksiya o'zgarishi 5+ faylga ta'sir qilmaydi, testlar 10 bog'liqlikni mock qilmasdan yoziladi, yangi dasturchi strukturani bir kunda tushunadi. SonarQube va detekt kabi vositalar SRP va DIP buzilishlarini aniqlashga yordam beradi.

Xulosa

  • SOLID — moslashuvchan va barqaror kod yaratish uchun besh OOP tamoyili (SRP, OCP, LSP, ISP, DIP)
  • SRP — har bir ob'ekt bitta vazifa uchun javobgar, God-sinf muammosini hal qiladi
  • OCP — mavjud kodni o'zgartirmasdan polimorfizm orqali kengaytirish
  • LSP — merosxo'rlar asosiy sinfning xatti-harakatini buzmasligi kerak
  • ISP — universal “Shveytsariya pichog'i” o'rniga tor interfeyslar
  • DIP — abstraksiyalarga bog'liqlik, Android-da Hilt/Koin orqali kiritish
  • SOLID Clean Architecture va tijorat mobil loyihalari uchun majburiy

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