ISP (Interface Segregation Principle) — SOLID ning to'rtinchi printsipi bo'lib, unda aytiladi: mijozlar foydalanmaydigan metodlarga bog'liq bo'lmasligi kerak. Printsip Robert Martin tomonidan ob'ektga yo'naltirilgan tizimlar uchun interfeyslarni loyihalash kontekstida shakllantirilgan. Clean Architecture (2017) kitobida ta'riflanganidek, interfeyslarni ajratish printsipi bitta universal interfeys o'rniga tor ixtisoslashtirilgan interfeyslar yaratishni talab qiladi, bu esa bog'liqlikni kamaytiradi va o'zgartirishlar kiritishni soddalashtiradi.
Asosiy
ISP (Interface Segregation Principle) — barcha mijozlar tomonidan foydalanilmaydigan metodlarga ega “qalin” interfeyslar yaratishni taqiqlovchi interfeyslarni ajratish printsipi. O'nta metodli bitta interfeys o'rniga, har biri o'z mijozlar guruhi uchun bir nechta kichik interfeyslar loyihalashtiriladi.
Printsip Robert Martin tomonidan “interfeyslarning ifloslanishi” muammosini hal qilish sifatida kiritilgan, bunda bir sinf umumiy interfeysda e'lon qilingani uchun unga kerak bo'lmagan metodlarni amalga oshirishga majbur bo'ladi. Statik tipli tillarda bu bo'sh amalga oshirishlarga yoki istisnolarni chiqarishga olib keladi — ISP ni buzishning bevosita belgisi.
ISP va SRP bir-birini to'ldiradi: SRP sinfning mas'uliyati haqida, ISP interfeyslarning shartnomalari haqida. SRP “bitta sinf — o'zgartirish uchun bitta sabab” deydi, ISP “bitta interfeys — bitta mijoz stsenariysi” deydi. Birgalikda tizimning har bir elementi aniq chegaralarga ega bo'lgan modulli arxitekturani shakllantiradilar.
Fat Interface — ma'lum bir mijozga kerak bo'lganidan ko'proq metodlarni o'z ichiga olgan interfeys. Masalan, work, eat, sleep metodlari bilan Worker interfeysi. Robot-ishchi eat va sleep ni amalga oshirmasligi kerak, lekin majbur. Yechim — Workable, Eatable, Sleepable ga bo'lish. Har bir mijoz aynan kerakli narsani oladi.
Mobil dasturlashda qalin interfeyslar delegat va DataSource protokollarida uchraydi. Bitta protokol ikki xil stsenariy (tahrirlash + ko'rsatish) uchun metodlarni o'z ichiga olishi mumkin, holbuki aniq ekran ulardan faqat bittasini ishlatadi.
ISP ni amalga oshirish har bir interfeysning mijozlarini tahlil qilish bilan boshlanadi. Agar ikki mijoz bitta interfeysning turli metod to'plamlaridan foydalansa — interfeys bo'linishi kerak. Har bir yangi interfeys bitta stsenariy doirasida birgalikda chaqiriladigan metodlarni guruhlaydi.
Bo'lish mexanizmi: asl interfeys bir nechta tor interfeyslarga bo'linadi, ularning har biri umumiy qismni (agar mavjud bo'lsa) meros qilib oladi. Mijozlar umumiy interfeys o'rniga kerakli tor interfeysga bog'liqlikka o'tadilar. Asl interfeysni amalga oshirgan sinflar endi faqat haqiqatan kerak bo'lgan tor interfeyslarni amalga oshiradilar.
Muhim aniqlik: bo'linish darajasi mijozlar soni va ularning stsenariylari bilan belgilanadi. ISP maksimal bo'linishni (har bir metod uchun mikrointerfeyslar) talab qilmaydi. Bu haddan tashqari murakkablikka olib keladi. Maqsad — mijozlarning keraksiz metodlarga bog'liqligini bartaraf etish, har bir interfeys hajmini minimallashtirish emas.
Asosiy belgilar ISP ni buzishga quyidagilar kiradi: sinflarning bo'sh metodlar bilan interfeysni amalga oshirishi (soxta amalga oshirish), amalga oshirishlarda UnsupportedOperationException istisnosini chiqarish, mijozlarning bir qismi tomonidan foydalanilmaydigan ko'p sonli parametrlar yoki qaytariladigan turlar, va mijozlarning faqat bir qismiga ta'sir qiladigan tez-tez interfeys o'zgarishlari.
Android dasturlashda ISP ni buzishning tipik namunasi — bosish, uzoq bosish va surish uchun metodlarni o'z ichiga olgan OnItemClickListener interfeysi. Agar aniq ekran faqat bosishdan foydalansa — qolgan metodlar bo'sh qoladi. Yechim — OnItemClickListener, OnItemLongClickListener, OnItemSwipeListener ga bo'lish.
iOS dasturlashda ISP ni buzish UIKit delegatlarida namoyon bo'ladi: bitta protokol komponentning turli holatlari uchun metodlarni o'z ichiga oladi. UITableViewDelegate ko'rsatish, tanlash, tahrirlash va surish harakatlari uchun metodlarni o'z ichiga oladi. Ko'pincha dasturchilar o'nta bo'sh metod bilan butun protokolni amalga oshiradilar. Mas'uliyat guruhlari bo'yicha bir nechta protokollarga bo'lish muammoni hal qiladi.
Muammo faqat kod estetikasida emas. Interfeys o'zgarganda (yangi metod qo'shilganda), barcha amalga oshiruvchi sinflar yangilanishi kerak — hatto yangi metodga muhtoj bo'lmaganlar ham. O'nlab ekranli mobil dasturlashda bu kaskad o'zgarishlarga olib keladi. ISP har bir mijozni unga tegishli bo'lmagan o'zgarishlardan izolyatsiya qiladi.
Yashirin ISP buzilishi konfiguratsiya parametrlari orqali sodir bo'ladi. Agar metod ko'p sonli maydonli ob'ektni qabul qilsa, mijoz esa ulardan faqat 2-3 tasini ishlatsa — bu bo'linish uchun signal. Alternativ: minimal parametr to'plamiga ega bir nechta ixtisoslashtirilgan metodlar.
Android dasturlashda ISP, ilovaning barcha sozlamalarini o'qish va yozish uchun bitta SharedPreferencesManager dan foydalanilganda buziladi. Faqat mavzuni o'qishi kerak bo'lgan Fragment, turli ma'lumot turlari uchun o'nta metodli global menejerga bog'liqlik oladi. ThemePreferenceProvider, AuthPreferenceProvider, FeatureFlagProvider ga bo'lish — konfiguratsiya xizmatlari darajasida ISP ni qo'llash. Har bir provayder o'z mijozlariga kerak bo'lgan aniq metodlarni o'z ichiga oladi.
Ma'lumotlar bilan ishlash uchun interfeysli Android misolini ko'rib chiqaylik. ISP ni buzish — barcha CRUD operatsiyalari uchun bitta interfeys, holbuki barcha mijozlarga barcha operatsiyalar kerak emas.
// ISP ni buzish: qalin interfeys
interface UserRepository {
fun getAll(): List<User>
fun getById(id: Int): User
fun save(user: User)
fun delete(id: Int)
}
// ISP qo'llanilgandan keyin: tor interfeyslar
interface UserReader {
fun getAll(): List<User>
fun getById(id: Int): User
}
interface UserWriter {
fun save(user: User)
fun delete(id: Int)
}
// ReadOnlyViewModel yozish metodlariga bog'liq emas
class ReadOnlyViewModel(
private val reader: UserReader
)
Media bilan ishlash uchun protokollarni bo'lish bilan iOS misoli:
// ISP ni buzish: media bilan ishlash uchun bitta protokol
protocol MediaService {
func play(url: URL)
func pause()
func stop()
func upload(data: Data) async -> URL
func download(url: URL) async -> Data
}
// ISP dan keyin: mas'uliyat bo'yicha protokollarga bo'lish
protocol MediaPlayer {
func play(url: URL)
func pause()
func stop()
}
protocol MediaTransfer {
func upload(data: Data) async -> URL
func download(url: URL) async -> Data
}
// PlayerViewModel yuklash metodlariga bog'liq emas
class PlayerViewModel {
private let player: MediaPlayer
}
Amaliy xulosa: ISP mijozlarni interfeysning ularga bog'liq bo'lmagan qismlaridagi o'zgarishlardan himoya qiladi. UserRepository ni UserReader va UserWriter ga bo'lish save dagi o'zgarishlar ReadOnlyViewModel ga ta'sir qilmasligini va aksincha ekanligini anglatadi. Har bir mijoz foydalanmaydigan funksionallikdan izolyatsiya qilingan va tizimning boshqa qismlari takomillashtirilganda o'zgartirishni talab qilmaydi.
ISP va SRP — tabiiy juftlik. SRP sinfning o'zgarish uchun bitta sababi bo'lishi kerakligini belgilaydi. ISP xuddi shu mantiqni interfeyslarga qo'llaydi: interfeys bitta mijoz stsenariysiga xizmat qilishi kerak. Sinf bir nechta tor interfeyslarni amalga oshirishi mumkin (har biri bitta mas'uliyatga mos keladi), bu bir nechta mas'uliyatli bitta qalin interfeysdan tozarog'dir.
ISP va OCP ham bog'liq: tor interfeyslarni kengaytirish osonroq. Tor interfeysga yangi metod qo'shish faqat uning mijozlariga ta'sir qiladi. Qalin interfeysga metod qo'shish barcha mijozlarga ta'sir qiladi — potensial ravishda OCP ni buzadi, agar mijozlar o'z amalga oshirishlarini o'zgartirishga majbur bo'lsalar.
ISP va DIP birgalikda ishlaydi: DIP abstraksiyalarga bog'liqlikni talab qiladi. ISP bu abstraksiyalarni tor va fokuslangan qiladi. Keng interfeysga bog'liqlik hali ham abstraksiyaga bog'liqlikdir, lekin ISP nuqtai nazaridan “yomon” abstraksiya. To'rtta printsip (SRP, OCP, ISP, DIP) “modullik piramidasini” tashkil qiladi: SRP va ISP chegaralarni belgilaydi, OCP va DIP — kengaytirish va bog'lash usullarini.
Komponent arxitekturasi mobil loyihalarda (modullar, xususiyatlar, qatlamlar) umumiy API darajasida ISP dan foyda oladi. Har bir modul o'z iste'molchilari uchun bitta umumiy fasad emas, balki tor interfeyslarni eksport qiladi. Bu modulning ichki amalga oshirilishini, uning funksionalligining faqat bir qismini ishlatadigan iste'molchilarga ta'sir qilmasdan o'zgartirish imkonini beradi.
Clean Architecture bilan Android loyihalarida ISP UseCase ga qo'llaniladi: har bir UseCase bitta invoke yoki execute metodli alohida interfeysdir. Mijoz (ViewModel) faqat kerakli UseCase ga bog'liq, butun repozitoriyga emas. Bu bog'liqliklarni shaffof va sinab ko'rish mumkin qiladi.
Tez-tez beriladigan savollar
Ha, haddan tashqari bo'lish mumkin. ISP har bir metod uchun bitta interfeysni talab qilmaydi. Mezon: interfeysning faqat bir qismiga muhtoj mijoz bormi? Agar barcha mijozlar barcha metodlardan foydalansa — interfeysni bo'lish shart emas. Optimal bo'lish darajasi real foydalanish stsenariylari bilan belgilanadi.
Parametrlar darajasida ISP degani: funksiya agar ulardan faqat bir qismini ishlatsa, ko'p sonli maydonli ob'ektlarni qabul qilmasligi kerak. Buning o'rniga faqat kerakli ma'lumotlarni uzatish yoki ixtisoslashtirilgan interfeyslardan foydalanish kerak (masalan, to'liq User o'rniga Renderable interfeysi).
LSP to'g'ri meros olish va pastki turlarning xatti-harakatlar muvofiqligi haqida. ISP interfeyslarni loyihalash haqida: mijozlar foydalanmaydigan metodlarga bog'liq bo'lmasligi kerak. LSP “pastki sinf asosiy sinf o'rniga ishlatilishi mumkinmi?” degan savolga javob beradi, ISP “mijozga butun interfeys kerakmi?” degan savolga.
Tor interfeyslar mock-ob'ektlar yaratishni osonlashtiradi: test o'nta metod bilan emas, balki bir-ikki metodli mock yaratadi. Interfeysda qancha kam metod bo'lsa, uning xatti-harakatini simulyatsiya qilish shuncha oson. Bu test dasturchisining kognitiv yukini kamaytiradi va mock mantig'idagi xatolik ehtimolini pasaytiradi.
Agar interfeys barqaror va barcha mijozlar barcha metodlardan foydalansa — bo'lish ortiqcha. Tipik misol: Apple tomonidan loyihalashtirilgan UIKit protokollari. Ularni bo'lish xavfli, chunki UIKit delegatning to'liq amalga oshirilishini kutadi. Bunday hollarda ISP ni buzish API barqarorligi bilan oqlanadi.
Xulosa
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.