Template Method — algoritmning umumiy skeletini base classda belgilab, ayrim qadamlarni subclasslarga o‘zgartirish imkonini beradigan behavioral design pattern. Asosiy qadamlar tartibi saqlanadi, o‘zgaruvchan qismlar esa override qilinadi.
Pattern bir xil workflow’ning bir nechta variantlarini yaratishda ishlatiladi.
Template method
Base classdagi asosiy method algoritm ketma-ketligini belgilaydi.
Masalan:
validate
→ load
→ transform
→ save
→ notify
Template method qadamlarni shu tartibda chaqiradi.
Subclass butun workflow’ni qayta yozmasdan kerakli qadamlarni o‘zgartiradi.
Primitive operation
Subclass amalga oshirishi shart bo‘lgan abstract qadam.
Masalan:
def load(self):
raise NotImplementedError
CSV importer va API importer load()ni turlicha bajaradi.
Template method esa keyingi transform va save tartibini saqlaydi.
Hook
Hook default bo‘sh yoki oddiy implementationga ega ixtiyoriy qadam.
Subclass xohlasa override qiladi.
Masalan:
before_save
after_save
should_notify
Concrete operation
Base classda to‘liq amalga oshirilgan va subclass o‘zgartirmasligi kerak bo‘lgan qadam.
Masalan:
- common validation;
- logging;
- transaction boundary;
- metrics;
- resource cleanup.
Bu umumiy qoidani barcha variantlarda bir xil saqlaydi.
Misol
Data import base classi:
run()
validate_source()
data = read()
normalized = transform(data)
persist(normalized)
after_import()
CSV, JSON va API importer faqat read() va ayrim transform qadamlarini override qilishi mumkin.
Inheritance
Template Method inheritancega tayanadi.
Base class algoritmni boshqaradi.
Subclass extension pointlarni to‘ldiradi.
Bu Hollywood Principle bilan ifodalanadi:
Bizga qo‘ng‘iroq qilmang, biz sizga qo‘ng‘iroq qilamiz.
Subclass template method tomonidan chaqiriladi.
Invariant qadamlar
Algoritmning o‘zgarmas qismi base classda qoladi.
Masalan, payment workflow’da:
- permission;
- idempotency;
- audit;
- transaction;
- final status
barcha providerlar uchun umumiy bo‘lishi mumkin.
Providerga xos remote call override qilinadi.
Override xavfi
Subclass template methodning o‘zini override qilsa umumiy invariantlarni chetlab o‘tishi mumkin.
Shuning uchun ayrim tillarda template method final yoki sealed qilinadi.
Faqat belgilangan hook va primitive operationlar override qilinadi.
Default implementation
Ba’zi qadamlar base classda ishlaydigan defaultga ega.
Subclass faqat farqli holatni o‘zgartiradi.
Bu code duplicationni kamaytiradi.
Default juda ko‘p assumption qilsa subclass behaviori noaniq bo‘lishi mumkin.
Template Method va Strategy
Template Method inheritance orqali algoritmning ayrim qadamlarini o‘zgartiradi.
Strategy composition orqali butun yoki ma’lum algoritm obyektini almashtiradi.
Template Method compile-time class hierarchyga yaqin.
Strategy runtime’da erkin almashtirilishi mumkin.
Template Method va Factory Method
Template method ichida obyekt yaratish qadami Factory Method sifatida berilishi mumkin.
Masalan:
create_parser()
subclass tomonidan override qilinadi.
Shunday qilib ikkala pattern birga ishlaydi.
Template Method va Hook
Hook subclassga optional extension beradi.
Hooklar ko‘payib ketsa base classning lifecycle’i juda murakkablashadi.
Qaysi hook qachon chaqirilishi va return qiymati algoritmga qanday ta’sir qilishi hujjatlashtiriladi.
Resource cleanup
Template method resource lifecycle’ni markazlashtirishi mumkin.
Masalan:
open
→ process
→ finally close
Subclass faqat processingni amalga oshiradi.
Shunda barcha variantlar file yoki connectionni to‘g‘ri yopadi.
Transaction boundary
Base class transactionni ochib, subclass qadamlarini ichida bajarishi mumkin.
Ammo subclass tashqi API’ni uzoq kutsa transaction ham uzoq ochiq qoladi.
Extension pointlar transaction semantikasini bilishi kerak.
Error handling
Template umumiy error policy beradi:
- validation errorni qaytarish;
- transient errorni retry;
- log;
- cleanup;
- status yangilash.
Subclass raw exceptionni domain errorga aylantirishi mumkin.
Xatoni jim yutish template natijasini noto‘g‘ri ko‘rsatadi.
Test
Base template uchun test double subclass yaratiladi.
U har qadam chaqirilgan tartibni yozadi.
Tekshiriladi:
- qadamlar tartibi;
- optional hook;
- failure’da cleanup;
- subclass override;
- invariant qadam;
- return qiymat propagation.
Har concrete subclass ham alohida test qilinadi.
Afzalliklari
Template Method:
- umumiy workflow’ni bir joyda saqlaydi;
- duplicationni kamaytiradi;
- qadam tartibini himoya qiladi;
- subclasslarga cheklangan extension beradi;
- resource va error handlingni markazlashtiradi.
Kamchiliklari
Inheritance coupling kuchayadi.
Base classdagi o‘zgarish barcha subclasslarga ta’sir qiladi.
Ko‘p hook va protected state fragile base class muammosini yaratadi.
Composition kerak bo‘lgan joyda inheritance ortiqcha bo‘lishi mumkin.
Liskov Substitution
Subclass base class contractini buzmasligi kerak.
Masalan, base save() muvaffaqiyatli bo‘lsa durable natija kutsa subclass faqat memory’da vaqtincha saqlab qo‘ymasligi kerak.
Template extensionlari preconditionni kuchaytirib yoki postconditionni zaiflashtirib yubormaydi.
Protected state
Base class ko‘p protected field ochsa subclass ichki implementationga bog‘lanadi.
Field o‘rniga kichik protected methodlar yoki immutable context berish xavfsizroq.
Bu base class refactoringini yengillashtiradi.
Compositionga o‘tish
Subclasslar soni va hooklar ko‘payganda workflow qadamlarini alohida strategy obyektlariga ajratish mumkin.
Template umumiy orchestrator bo‘lib qoladi, o‘zgaruvchan qadamlar composition orqali inject qilinadi.
Bu runtime konfiguratsiyani yaxshilaydi.
Dokumentatsiya
Template qaysi qadamlarni chaqirishi, qaysi hook ixtiyoriy va qaysi exceptionlar tarqalishi aniq hujjatlashtiriladi.
Subclass muallifi lifecycle’ni source code’dan taxmin qilishga majbur bo‘lmasligi kerak.
Bog‘liq tushunchalar
Behavioral pattern, Inheritance, Hook, Primitive operation, Strategy Pattern, Factory Method, Hollywood Principle, Algorithm skeleton, Base class