Biz allaqachon Singleton kabi sinf obyektini ishlatish sxemasidan o'tdik, lekin balki sen hali bilmasliging mumkin, lekin bu loyihalash namunalardan biri, eng ko'p qo'llaniladiganlaridan biri.
Darhaqiqat juda ko'p turli xildagi namunalari bor, undan tashqari - ular o'z iyerarxiyasiga ega va har bir namunani o'z maqsadi bor.
Patternlar Klassifikatsiyasi
| Pattern turi | Qo'llanishi |
|---|---|
| Yaratish | Obyektlar yaratish muammosini hal qiluvchi tur |
| Strukturaviy | Bizning arxitekturamizda to'g'ri, kengayishga mos iyerarxiyani qurish imkonini beradigan naqshlar |
| Xulq-atvorga oid | Bu klaster naqshlari dastur ob'ektlari o'rtasida xavfsiz va qulay aloqani qabul qiladi |
Odatda pattern hal qiladigan muammo bilan xarakterlanadi. Keling, Java bilan ishlashda eng ko'p duch keladigan namunalarni ko'rib chiqaylik:
| Pattern | Maqsad |
|---|---|
| Singleton | Biz allaqachon tanishmiz va uni bitta nusxada bo'lishi mumkin emas bo'lgan sinf yaratish va murojaat qilish uchun ishlatamiz. |
| Iterator | Biz, asosan, tanishmiz va bilamizki, ushbu pattern bizga ichki ko'rinishini ochmasdan tarkibini aytishga imkon beradi. To'plamlar bilan ishlatiladi. |
| Adapter | Birgalikda ishlash uchun noto'g'ri ob'ektlarni bog'lash. O'ylaymanki, adapter haqida gapirganda har bir kishi aynan nima qiladigan patternni anglatayotganini tasavvur qiladi. Hayotdan oddiy misol - USB adapter - vilka rozetkaga. |
| Template Method | Dasturlash uslubidan biri bo'lib, integratsiya muammosini hal qiladi va algoritmning tuzilishini o'zgartirmasdan uning qadamlarini o'zgartiradi. Avtomobil yig'ish algoritmi bir ketma ketlikda yig'ilishini tasavvur qilaylik: Shassi -> Korpus -> Motor -> salon yig'ish Agar biz kuchli ramka, kuchli motor yoki qo'shimcha yoritish bilan salon qo'ysak ham, algoritmni o'zgartirmaymiz, va abstrakt ketma-ketlik o'sha qoladi. |
| Decorator | Ob'ektlarga qo'shimcha foydali funktsionallik qo'shish uchun o'ramlarni yaratadi. Uni biz ushbu maqola kontekstida ko'rib chiqamiz. |
Java.io da patternlar quyidagi sinflarda amalga oshiriladi:
| Pattern | Java.io da qaerda ishlatiladi |
|---|---|
| Adapter |
|
| Template Method | |
| Decorator |
Dekorator Patterni
Uy loyihalash modelini tasavvur qilaylik.
Umumiy sxema quyidagicha bo'ladi:
Dastlab bizda bir necha turdagi uy tanlovi bor. Minimal konfiguratsiya - bitta qavat va tom, keyinchalik - dekortorlar yordamida har qanday turdagi qo'shimcha parametrlar bilan o'zgartirilishi mumkin va bu uy narxiga ta'sir qiladi.
Abstrakt uy sinfini yaratamiz:
public abstract class House {
String info;
public String getInfo(){
return info;
}
public abstract int getPrice();
}
Bu yerda bizda 2 usul bor:
- getInfo() uy nomi va konfiguratsiyasi haqida ma'lumotni qaytaradi;
- getPrice() — uy narxini joriy konfiguratsiyada.
Shuningdek, bizda odatiy uy implemetatsiyalari bor - g'ishtli va yog'ochdan yasalgan:
public class BrickHouse extends House {
public BrickHouse() {
info = "G'ishtli uy";
}
@Override
public int getPrice() {
return 20_000;
}
}
public class WoodenHouse extends House {
public WoodenHouse() {
info = "Yog'och uy";
}
@Override
public int getPrice() {
return 25_000;
}
}
Ikkala sinf ham House sinfidan meros olgan va narx metodini qayta yozib, standart uy uchun individual narx belgilaydi. Konstruktorida ismni tayinlaymiz.
Keyin biz dekorator sinflarini yozishimiz kerak. Bular House sinfidan ham meros olgan sinflardir. Buning uchun biz dekoratsiya qilishning abstrakt sinfini yaratamiz.
Biz unga ob'ektni o'zgartirish uchun qo'shimcha mantiq qo'shishimiz mumkin. Bizning holatda qo'shimcha mantiq bo'lmaydi va abstrakt sinf bo'sh qoladi.
abstract class HouseDecorator extends House {
}
Keyin dekoratorlarni amalga oshirish sinflarini yaratamiz. Biz bir nechta sinflarni yaratamiz, bu uylarga qo'shimcha parametrlar qo'shishga imkon beradi:
public class SecondFloor extends HouseDecorator {
House house;
public SecondFloor(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 20_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + ikkinchi qavat";
}
}
| Bizning uyga ikkinchi qavat qo'shadigan dekorator |
Dekoratorda uy qabul qilinadi, unga dekoratordan o'zgarishlar qo'llaymiz. Usullar getPrice() va getInfo()ni qayta yozamiz, eski uydan yaratilgan yangi modernizatsiyalangan uy haqida ma'lumotni qaytarish.
public class Garage extends HouseDecorator {
House house;
public Garage(House house) {
this.house = house;
}
@Override
public int getPrice() {
return house.getPrice() + 5_000;
}
@Override
public String getInfo() {
return house.getInfo() + " + garaj";
}
}
| Uyga garaj qo'shadigan dekorator |
Endi biz uyni dekoratorlar yordamida o'zgartirishimiz mumkin. Buning uchun uy yaratish kerak:
House brickHouse = new BrickHouse();
Keyin bizning house o'zgaruvchisiga yangi qiymat tayinlaymiz, bu bizning uyimizni uzatamiz:
brickHouse = new SecondFloor(brickHouse);
Bizning house o'zgaruvchimiz allaqachon ikkinchi qavatli uyga ega.
Keling dekoratorlar ishlatiladigan holatlarni ko'rib chiqaylik:
| Kod namunasi | Natija |
|---|---|
|
G'ishtli uy 20000 |
|
G'ishtli uy + ikkinchi qavat 40000 |
|
G'ishtli uy + ikkinchi qavat + garaj 45000 |
|
Yog'och uy + garaj + ikkinchi qavat 50000 |
|
Yog'och uy 25000 Yog'och uy + garaj 30000 |
Ushbu misolda biz dekorator yordamida ob'ektni yangilashning afzalligini ko'ramiz. Ko'rinib turibdiki, biz woodenHouse ob'ektini o'zgartirmadik, lekin yangi ob'ekt yaratdik. Ammo bu afzallik orqali, biz har safar yangi ob'ekt yaratib, xotiraga qo'shimcha yuklamalar qo'shamiz.
Bizning dasturimizning UML diagrammasini ko'rib chiqaylik:
Dekorator nisbatan oson amalga oshiriladi va ob'ektlarni dinamik o'zgartirish, ularni modernizatsiya qilish uchun qo'llaniladi. Dekoratorni parametrlarida o'sha abstrakt tur yoki interfeysdagi ob'ektlarni qabul qiladigan konstruktorlar orqali aniqlash mumkin. Java'da ushbu pattern keng tarqalgan holda kirish/chiqish sinflarida qo'llaniladi.
Masalan, biz allaqachon ta'kidlab o'tdik, barcha java.io.InputStream, OutputStream, Reader va Writer sinflari o'sha sinflarning ob'ektlarini qabul qiladigan konstruktoriga ega.
GO TO FULL VERSION