Iterator Pattern — collectionning ichki tuzilishini oshkor qilmasdan uning elementlari bo‘ylab ketma-ket yurish imkonini beradigan behavioral design pattern. Iterator traversal holatini alohida obyekt yoki protocol ichida saqlaydi.
Client collection array, linked list, tree, database cursor yoki stream ekanini bilmasdan bir xil usulda elementlarni olishi mumkin.
Muammo
Collection turiga qarab traversal farq qiladi:
- array — index;
- linked list — next pointer;
- tree — stack yoki recursion;
- graph — visited set;
- database — cursor;
- paginated API — token.
Agar client bu detallarni bilsa collection implementationiga qattiq bog‘lanadi.
Iterator traversalni abstraction qiladi.
Iterator interface
Klassik iterator quyidagi operationlarga ega:
has_next()— keyingi element mavjudmi;next()— keyingi elementni qaytarish;- ayrim hollarda
current()yokireset().
Zamonaviy tillarda iterator protocol va for loop bu amallarni yashiradi.
Aggregate
Collection yoki Aggregate iterator yaratish methodini beradi.
Masalan:
iterator = collection.iterator()
Bir collection turli iteratorlar berishi mumkin:
- oldinga;
- orqaga;
- filtrlangan;
- depth-first;
- breadth-first.
Traversal state
Iterator joriy pozitsiyani saqlaydi.
Array uchun index.
Tree uchun stack.
Graph uchun queue va visited set.
Pagination uchun next token.
State collection ichida emas, iterator ichida bo‘lsa bir collection ustida bir nechta mustaqil traversal mumkin.
External iterator
Client traversalni o‘zi boshqaradi.
while iterator.has_next():
item = iterator.next()
Client qachon keyingi element olinishi va qachon to‘xtashni nazorat qiladi.
Ko‘p dasturlash tillaridagi iteratorlar shunday.
Internal iterator
Collection callback qabul qilib traversalni o‘zi boshqaradi.
collection.for_each(callback)
Client element ustidagi amalni beradi, ammo traversal qadamlarini boshqarmaydi.
Parallel yoki optimized traversal uchun qulay.
Lazy iteration
Iterator barcha natijani oldindan memory’ga yuklamasdan elementlarni kerak bo‘lganda ishlab chiqaradi.
Bu:
- katta file;
- generator;
- database cursor;
- remote pagination;
- infinite sequence
uchun foydali.
Client traversalni erta to‘xtatsa qolgan elementlar hisoblanmaydi.
Generator
Generator function iterator yaratishning qulay usuli.
U yieldga o‘xshash operation orqali qiymat qaytaradi va execution holatini saqlaydi.
Generator qo‘lda class yozishni kamaytiradi.
Resource cleanup uchun generator yopilishi kerak bo‘lishi mumkin.
Fail-fast iterator
Collection traversal davomida strukturaviy o‘zgarsa iterator xato beradi.
Masalan, listga yangi element qo‘shildi.
Bu noaniq natijani oldini oladi.
Fail-fast concurrency kafolati emas; u best-effort detection bo‘lishi mumkin.
Snapshot iterator
Traversal boshida collectionning snapshoti olinadi.
Keyingi o‘zgarishlar iterator natijasiga ta’sir qilmaydi.
Afzalligi — barqaror traversal.
Kamchiligi — nusxa memory va eski data.
MVCC database cursor bunga yaqin semantika berishi mumkin.
Live iterator
Collectiondagi keyingi o‘zgarishlarni ko‘rishi mumkin.
Bu dynamic stream uchun qulay.
Ammo element skip, duplicate yoki tartib o‘zgarishi mumkin.
Semantika aniq hujjatlashtiriladi.
Tree iterator
Tree uchun traversal variantlari:
- preorder;
- inorder;
- postorder;
- breadth-first.
Har biri boshqa natija tartibini beradi.
Iterator stack yoki queue orqali recursionni explicit statega aylantiradi.
Graph iterator
Graph cycle’ga ega bo‘lishi mumkin.
Iterator visited node’larni saqlaydi.
Aks holda bir node qayta-qayta yurilib, traversal tugamasligi mumkin.
Yo‘nalish va edge filter ham iterator strategiyasiga kiradi.
Database iterator
Query natijasi server-side cursor orqali batchlarda olinadi.
Iterator clientga rowlarni bittadan ko‘rsatishi mumkin.
Ichkarida esa fetch size bo‘yicha guruhlab network request yuboradi.
Traversal tugaganda cursor va connection yopiladi.
Paginated API iterator
API har javobda next token qaytaradi.
Iterator tokenni yashirib, clientga oddiy element stream beradi.
U:
holatlarini boshqaradi.
Infinite iterator
Ba’zi iteratorlar tugamaydigan sequence beradi.
Masalan:
Bunday iterator bilan to_list()ga o‘xshash operation memoryni tugatishi mumkin.
Client limit yoki cancellation beradi.
Iterator va Iterable
Iterable iterator yaratishi mumkin bo‘lgan obyekt.
Iterator esa joriy traversal holatini saqlaydi.
Bir iterable’dan bir nechta iterator yaratilishi mumkin.
Iteratorning o‘zi ko‘pincha bir marta ishlatiladi.
Concurrency
Bir collectionni boshqa thread o‘zgartirayotgan paytda iterator natijasi noaniq bo‘lishi mumkin.
Yondashuvlar:
- lock;
- snapshot;
- immutable collection;
- concurrent collection;
- copy-on-write.
Iterator thread-safe ekanini avtomatik taxmin qilish mumkin emas.
Resource management
File, cursor yoki network iterator resource saqlaydi.
Traversal to‘liq tugamasa ham resource yopilishi kerak.
Context manager, finally yoki explicit close() ishlatiladi.
Garbage collectionga tayanish connection leak yaratishi mumkin.
Iterator invalidation
Collection elementlari o‘chirilsa yoki storage qayta tashkil qilinsa mavjud iterator pozitsiyasi yaroqsiz bo‘lishi mumkin.
Array reallocation, tree mutation yoki database cursor close bunga misol.
Library invalidation qoidalarini aniq belgilaydi.
Peek
Ayrim iterator keyingi elementni iste’mol qilmasdan ko‘rish uchun peek() beradi.
Parser va token streamlarda foydali.
Peek ichki buffer saqlashi mumkin.
Infinite yoki network iteratorida bu operation ham blocking bo‘lishi ehtimoli bor.
Parallel iteration
Collection partitionlarga bo‘linib parallel iteratorlar bilan qayta ishlanishi mumkin.
Natija tartibini saqlash qo‘shimcha merge talab qiladi.
Side effectli processing parallel bajarilganda thread safety va idempotency hisobga olinadi.
Bog‘liq tushunchalar
Behavioral pattern, Iterable, Generator, Cursor, Lazy evaluation, Traversal, Collection, Snapshot, Pagination, Resource management