JavaRush /Kurslar /All lectures for UZ purposes /Fabrikatsion usul shabloni

Fabrikatsion usul shabloni

All lectures for UZ purposes
Daraja, Dars
Mavjud

Ehtimol shu paytgacha sen loyihalash shablonlari bilan tanishgandirsan. Masalan, singleton (singleton).

Keling, shablonlar nima, nima uchun kerak, nima qilishlari kerak bo'lgan shablonlar (ular orasida singleton) va yangi shablon - fabrikatsion usulni o'rganamiz.

Loyihalash shabloni yoki shablon (design pattern) dasturiy ta'minot ishlab chiqishda tez-tez uchraydigan kontekstda loyihalash muammolarini hal qilish uchun takrorlanadigan arxitekturaviy tuzilmadir.

Odatda shablon to'liq tayyor yechim emas, u muammoni hal qilish uchun bir misol bo'lib, turli holatlarda qo'llanishi mumkin.

Poroja shablonlar (creational patterns) — loyihalash shablonlari bo'lib, ob'ekt yaratish jarayonini boshqaradi. Ular tizimni ob'ektlarni yaratish, kompozitsiya va tasvirlash usulidan mustaqil qilish imkonini beradi.

Fabrikatsion usul (factory method) — bu poroja shabloni bo'lib, bu usulda ob'ektlarni yaratish uchun umumiy interfeys aniqlanadi va bu ob'ektlarni yaratish uchun o'z vorislari orqali berilgan bo'ladi. Yaratuvchi vorislar qaysi sinfni yaratishni aniqlashlari mumkin.

Muammo qanday hal qilinadi?

Tasavvur qil, dastur yetkazib berishni yaratishga qaror qilding. Avvaliga dasturda yetkazib berish vositasi sifatida Avtomobil ob'ektidan foydalanib, avtomobillar bilan kuryerlarni ishga olasan. Kuryerlar posilkalarni A punktidan B, V va hokazolariga tashiydilar. Hammasi oddiy.

Dastur ommalashmoqda, biznesing o'smoqda va yangi bozorlarga chiqishni xohlaysan. Shunday qilib, qo'shimcha ravishda oziq-ovqatni yetkazib berishni va yuk tashishni boshlash mumkin. Unda oziq-ovqatni piyoda kuryerlar, samokatlar va velosipedlar orqali yetkazish mumkin, yuklar uchun esa yuk mashinalari kerak bo'ladi.

Endi qachon, kimga, nima va qancha yetkazib berilishini bilish muhim, har bir kuryer qancha tashishi yoki ko'tarishi mumkinligini hisobga olgan holda. Yangi turdagi transport vositalarining tezligi va sig'imi turlicha. Shunda dasturdagi ko'pchilik mavjudotlar Avtomobil ob'ektiga juda bog'liqligini ko'rasiz va boshqa yetkazib berish usullari bilan ishlash uchun dasturingizni ishga tushirish uchun mavjud kod bazasini qayta yozishga majbur bo'lasiz va har safar yangi transport uchun takrorlashingiz kerak bo'ladi.

Natijada, transport turiga qarab turli harakatlarni bajarayotgan shartli operatorlarga to'la dahshatli kod yaratiladi.

Muammoni hal qilish

Fabrikatsion usul ob'ektlarni to'g'ridan-to'g'ri new operatoridan foydalanib yaratish o'rniga o'ziga xos fabrikatsion usul orqali yaratishni taklif qiladi. Fabrikatsion usulni o'z ichiga olgan sinfning yetakchisi sinfi, yaratish mumkin bo'lgan transport vositalarining aniq sinflarini o'zgartirishi mumkin. Bir qarashda bu befoyda bo'lib tuyulishi mumkin: biz konstruktor chaqiruvini dasturning bir uchidan boshqa uchiga ko'chirdik. Ammo endi fabrikatsion usulni dastlabki sinfda qayta aniqlash orqali yaratish transport turini o'zgartirishingiz mumkin.

Klass diagrammasidagi yondashuvga qaraymiz:

Bu tizim ishlashi uchun barcha qaytarilgan ob'ektlar umumiy interfeysga ega bo'lishi kerak. Voris sinflar har xil sinflarining bir xil interfeysga amal qiladigan ob'ektlarini ishlab chiqarishi mumkin bo'ladi.

Masalan, Truck va Car sinflari Courier Transport interfeysini deliver metodi bilan amalga oshiradi. Bu sinflarning har biri o'z usulini amalga oshiradi: yuk mashinalari yuklarni yetkazib beradilar, avtomobillar oziq-ovqat, posilkalar va hokazolarni yetkazib beradilar. TruckCreator sinfidagi fabrikatsion usul yuk mashinasi ob'ektini qaytaradi, CarCreator sinfi esa avtomobil ob'ektini.

Fabrikatsion usulning mijozlari uchun bu ob'ektlar orasida hech qanday farq yo'q, chunki ularni bir xil abstrakt Courier Transport sifatida ko'rib chiqadi. Ular uchun ob'ektning metod deliverga ega bo'lishi muhim, lekin u qanday ishlashi muhim emas.

Java tilidagi amalga oshirish:


public interface CourierTransport {
	void deliver();
}
public class Car  implements CourierTransport{
	@Override
	public void deliver() {
    		System.out.println("Posilka avtomobil orqali yetkazildi ");
	}
}
public class Truck implements CourierTransport{
	@Override
	public void deliver() {
    		System.out.println("Yuk yuk mashinasi orqali yetkazildi");
	}
}
public abstract class CourierTransportCreator {
	public abstract CourierTransport createTransport();
}
public class CarCreator extends CourierTransportCreator {
	@Override
	public CourierTransport createTransport() {
    		return new Car();
	}
}
public class TruckCreator extends CourierTransportCreator{
	@Override
	public CourierTransport createTransport() {
    		return new Truck();
	}
}
 
public class Deliver {
	private String address;
	private CourierTransport courierTransport;
 
	public Deliver() {
	}
 
	public Deliver(String address, CourierTransport courierTransport) {
    	this.address = address;
    	this.courierTransport = courierTransport;
	}
 
	public CourierTransport getCourierTransport() {
    		return courierTransport;
	}
 
	public void setCourierTransport(CourierTransport courierTransport) {
    		this.courierTransport = courierTransport;
	}
 
	public String getAddress() {
    		return address;
	}
 
	public void setAddress(String address) {
    		this.address = address;
	}
}
public static void main(String[] args) {
    	//bazadan yangi turdagi buyurtma qabul qilamiz (psevdokod)
    	String type = database.getTypeOfDeliver();
 
    	Deliver deliver = new Deliver();
    	
    	//dostavkaga transport qo'shamiz
        deliver.setCourierTransport(getCourierTransportByType(type));
    	
    	//yetkazib beramiz
        deliver.getCourierTransport().deliver();
 
	}
 
	public static CourierTransport getCourierTransportByType(String type) {
    	switch (type) {
        	case "CarDeliver":
            	return new CarCreator().createTransport();
        	case "TruckDeliver":
            	return new TruckCreator().createTransport();
        	default:
            	throw new RuntimeException();
	    }
	}
    

Agar yangi yetkazib berish ob'ektini yaratishni xohlasak, dastur avtomatik ravishda biz uchun transport ob'ektini yaratadi.

Shablonni qachon qo'llash kerak?

1. Turlari va ob'ektlar bilan ishlaydigan kodning bog'liqliklarini oldindan bilmagan paytda.

Fabrikatsion usul transport ishlab chiqarish kodini uni ishlatadigan boshqa koddan ajratadi. Natijada ob'ekt yaratish kodini kengaytirish mumkin, asosiy kodga teginmasdan.

Shunday qilib, yangi turdagi transportni qo'llab-quvvatlash uchun yangi sinf yaratishingiz va undagi fabrikatsion usulni aniqlashingiz kerak bo'ladi va yangi transportdan namunani qaytarishingiz kerak.

2. Sistem resurslarini tejash uchun yangi ob'ektlar yaratish o'rniga allaqachon mavjud ob'ektlardan foydalangan paytda.

Bunday muammo og'ir resurs talab qiladigan ob'ektlar, masalan, ma'lumotlar bazasiga ulanish, fayl tizimiga ulanish va hokazolar bilan ishlaganda yuzaga keladi.

Eski ob'ektlarni takroran ishlatish uchun qancha harakat qilish kerakligini o'ylab ko'ring:

  1. Dastlab, mavjud barcha ob'ektlarni saqlash uchun umumiy saqlashni yaratishingiz kerak.

  2. Yangi ob'ekt so'ralgan paytda saqlashga kirib, foydalanilmagan ob'ekt mavjudligini tekshirish kerak.

  3. Ob'ektni mijoz kodiga qaytaring.

  4. Agar bo'sh ob'ektlar yo'q bo'lsa — yangi ob'ekt yarating va uni saqlashga qo'shing.

Butun bu kodni bir joyga joylashtirish kerak, shunda mijoz kodi ifloslanmaydi. Eng qulay joy ob'ektning konstruktori bo'lar edi, chunki bu tekshiruvlar faqat ob'ektlar yaratilishida kerak. Afsuski, konstruktor har doim yangi ob'ektlar yaratadi, mavjud nusxani qaytarolmaydi.

Demak, mavjud bo'lgan va yangi ob'ektlarni qaytaradigan boshqa metod kerak. U fabrikatsion usul bo'ladi.

3. Foydalanuvchilarga freymvork yoki kutubxonangizning qismlarini kengaytirish imkoniyatini bergan paytda.

Foydalanuvchilar freymvorkingizni vorislik orqali kengaytirishi mumkin. Ammo qanday qilib freymvork yangi sinflardan emas, balki standartlardan ob'ektlar yaratadigan qilasiz?

Yechar yo'l foydalanuvchilarga nafaqat istalgan komponentlarni, balki bu komponentlarni yaratadigan sinflarni ham kengaytirish imkoniyatini berishdir. Buning uchun yaratuvchi sinflar aniq yaratuvchi metodlarga ega bo'lishi kerak, ularni aniqlash mumkin bo'lgan.

Afzalliklar

  • Sinfni aniq transport sinflariga bog'lanishdan xalos qiladi.
  • Transport yaratish kodini bir joyga ajratib, kodni qo'llab-quvvatlashni soddalashtiradi.
  • Dasturga yangi transport turlarini qo'shishni osonlashtiradi.
  • Ochiqlik/zatvorlik prinsipini amalga oshiradi.

Kamchiliklar

Har bir mahsulot sinfi uchun yaratuvchi voris sinf yaratish kerak bo'lganligi sababli katta parallel vorislik ierarxiyalarini yaratishi mumkin.

Xulosa qilamiz

Fabrikatsion usul shabloni bilan tanishding va uning mumkin bo'lgan amalga oshirilishini ko'rding. Bu shablon turli kutubxonalarda tez-tez qo'llaniladi, ular esa o'z navbatida ob'ektlar yaratish va ob'ektlar yaratish imkoniyatini beradi.

Fabrikatsion usul shablonidan foydalangan holda, dasturingga yangi ob'ektlarni — mavjud bo'lgan sinflar asosida birlashtirish uchun qo'llab-quvvatlashni osongina qo'shish uchun foydalaning va asosiy biznes-logikaga tegmasdan qabul qilinadigan muhitning ko'payishiga sabab bo'lishdan saqlaning.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION