JavaRush /Java blogi /Random-UZ /Dizayn naqshlari: FactoryMethod

Dizayn naqshlari: FactoryMethod

Guruhda nashr etilgan
Salom! Bugun biz dizayn naqshlarini o'rganishni davom ettiramiz va zavod usuli (FactoryMethod) haqida gapiramiz. Dizayn naqshlari: FactoryMethod - 1Bu nima ekanligini va ushbu shablon qanday vazifalarga mos kelishini bilib olasiz. Biz ushbu dizayn naqshini amalda ko'rib chiqamiz va uning tuzilishini o'rganamiz. Yuqoridagilarning barchasi sizga tushunarli bo'lishi uchun siz quyidagi mavzularni tushunishingiz kerak:
  1. Java-da meros.
  2. Java tilidagi abstrakt usullar va sinflar.

Zavod usuli qanday muammoni hal qiladi?

Barcha zavod dizayn namunalarida ishtirokchilarning ikki guruhi mavjud - yaratuvchilar (zavodlarning o'zlari) va mahsulotlar (zavodlar tomonidan yaratilgan ob'ektlar). Vaziyatni tasavvur qiling: bizda AutoRush brendi ostida avtomobillar ishlab chiqaradigan zavod bor. U har xil turdagi korpuslarga ega avtomobil modellarini qanday yaratishni biladi:
  • sedanlar
  • stansiya vagonlari
  • kupe
Biz uchun ishlar shu qadar yaxshi ketayotgan ediki, bir kuni biz OneAuto konsernini o'zimizga singdirdik. Aqlli menejerlar sifatida biz OneAuto mijozlarini yo'qotmoqchi emasmiz va bizning vazifamiz ishlab chiqarishni ishlab chiqarishni shunday qayta tashkil etishdir:
  • AutoRush sedanlari
  • AutoRush stantsiya vagonlari
  • kupe AutoRush
  • OneAuto sedanlari
  • OneAuto stantsiya vagonlari
  • OneAuto kupe
Ko'rib turganingizdek, lotin mahsulotlarning bir guruhi o'rniga ba'zi tafsilotlarda farq qiladigan ikkitasi paydo bo'ldi. Zavod usuli dizayn namunasi har biri o'ziga xos xususiyatlarga ega bo'lgan turli xil mahsulotlar guruhlarini yaratish muammosini hal qiladi. Biz ushbu shablonning printsipini amalda ko'rib chiqamiz, asta-sekin oddiydan murakkabga o'tamiz, avvalgi ma'ruzalardan birida yaratgan qahvaxonamiz misolida .

Zavod shablonlari haqida bir oz

Sizga eslatib o'taman: biz siz bilan kichik virtual qahvaxona qurdik. Unda biz oddiy zavod yordamida turli xil qahva turlarini yaratishni o'rgandik. Bugun biz ushbu misolni aniqlaymiz. Keling, oddiy zavodga ega qahvaxonamiz qanday ko'rinishga ega bo'lganini eslaylik. Bizda kofe darsi bor edi:
public class Coffee {
    public void grindCoffee(){
        // перемалываем кофе
    }
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
Shuningdek, uning bir qancha merosxo'rlari - fabrikamiz ishlab chiqarishi mumkin bo'lgan kofe turlari:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Buyurtmalarni qabul qilish qulayligi uchun biz o'tkazmalarni joriy qildik:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Qahva fabrikasining o'zi shunday ko'rinardi:
public class SimpleCoffeeFactory {
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
Va nihoyat, qahvaxonaning o'zi:
public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }
}

Oddiy zavodni modernizatsiya qilish

Bizning qahvaxonamiz yaxshi ishlaydi. Shu qadar ko'pki, biz kengaytirish haqida o'ylayapmiz. Biz bir nechta yangi nuqtalarni ochmoqchimiz. Tashabbuskor yigitlar sifatida biz monoton qahvaxonalarni yo'qotmaymiz. Men har birining o'ziga xos burilish bo'lishini xohlayman. Shuning uchun, boshlash uchun biz ikkita nuqta ochamiz: italyan va amerikacha uslublarda. O'zgarishlar nafaqat ichki makonga, balki ichimliklarga ham ta'sir qiladi:
  • italyan qahvaxonasida biz maxsus maydalash va qovurish bilan faqat italyan kofe brendlaridan foydalanamiz.
  • Amerika qismi biroz kattaroq bo'ladi va har bir buyurtma bilan biz eritilgan marshmallowlar - marshmallowlarni taqdim etamiz.
O'zgarishsiz qoladigan yagona narsa - bu o'zini yaxshi isbotlagan biznes modelimiz. Agar biz kod tilida gapiradigan bo'lsak, shunday bo'ladi. Bizda 4 turdagi mahsulotlar bor edi:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Va u 8 ga aylanadi:
public class ItalianStyleAmericano extends Coffee {}
public class ItalianStyleCappucino extends Coffee {}
public class ItalianStyleCaffeLatte extends Coffee {}
public class ItalianStyleEspresso extends Coffee {}

public class AmericanStyleAmericano extends Coffee {}
public class AmericanStyleCappucino extends Coffee {}
public class AmericanStyleCaffeLatte extends Coffee {}
public class AmericanStyleEspresso extends Coffee {}
Biz joriy biznes modelini o'zgarmagan holda saqlashni xohlayotganimiz sababli, usul orderCoffee(CoffeeType type)minimal miqdordagi o'zgarishlarga duchor bo'lishini xohlaymiz. Keling, buni ko'rib chiqaylik:
public Coffee orderCoffee(CoffeeType type) {
    Coffee coffee = coffeeFactory.createCoffee(type);
    coffee.grindCoffee();
    coffee.makeCoffee();
    coffee.pourIntoCup();

    System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
    return coffee;
}
Bizda qanday variantlar bor? Biz zavodni qanday yozishni allaqachon bilamiz, to'g'rimi? Darhol aqlga keladigan eng oddiy narsa - ikkita o'xshash zavodni yozish va keyin kerakli dasturni konstruktordagi qahvaxonamizga o'tkazish. Shunda qahvaxonaning sinfi o'zgarmaydi. Birinchidan, biz yangi zavod sinfini yaratishimiz, oddiy zavodimizdan meros olishimiz va createCoffee (CoffeeType type). Keling, italyan va amerikacha uslubda qahva yaratish uchun fabrikalarni yozaylik:
public class SimpleItalianCoffeeFactory extends SimpleCoffeeFactory {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}

public class SimpleAmericanCoffeeFactory extends SimpleCoffeeFactory{

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }

}
Endi biz CoffeeShop-ga kerakli zavodni amalga oshirishimiz mumkin. Keling, turli xil qahvaxonalardan kofe buyurtma qilish uchun kod qanday ko'rinishini ko'rib chiqaylik. Masalan, italyan va amerikacha uslubdagi kapuchino:
public class Main {
    public static void main(String[] args) {
        /*
            Закажем капучино в итальянском стиле:
            1. Создадим фабрику для приготовления итальянского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику итальянского кофе
            3. Закажем наш кофе
         */
        SimpleItalianCoffeeFactory italianCoffeeFactory = new SimpleItalianCoffeeFactory();
        CoffeeShop italianCoffeeShop = new CoffeeShop(italianCoffeeFactory);
        italianCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);


         /*
            Закажем капучино в американском стиле
            1. Создадим фабрику для приготовления американского кофе
            2. Создадим новую кофейню, передав ей в конструкторе фабрику американского кофе
            3. Закажем наш кофе
         */
        SimpleAmericanCoffeeFactory americanCoffeeFactory = new SimpleAmericanCoffeeFactory();
        CoffeeShop americanCoffeeShop = new CoffeeShop(americanCoffeeFactory);
        americanCoffeeShop.orderCoffee(CoffeeType.CAPPUCCINO);
    }
}
Biz ikkita turli qahvaxona yaratdik, har birini kerakli zavodga o'tkazdik. Bir tomondan maqsadimizga erishdik, bir tomondan... Nimadir tadbirkorning tinimsiz ruhini tirnayapti... Keling, nima bo‘lganini aniqlaylik. Birinchidan, zavodlarning ko'pligi. Har safar yangi nuqta uchun o'z zavodingizni yaratish va qo'shimcha ravishda qahvaxonani yaratishda kerakli zavod konstruktorga o'tkazilishiga ishonch hosil qilish mumkinmi? Ikkinchidan, u hali ham oddiy zavod. Bir oz modernizatsiya qilingan. Biz bu erda hali ham yangi naqshni o'rganmoqdamiz. Uchinchidan, buni boshqacha qilish mumkin emasmi? Agar biz sinfda qahva tayyorlash bo'yicha barcha savollarni lokalizatsiya qilsak CoffeeShop, qahva yaratish va buyurtmaga xizmat ko'rsatish jarayonlarini bog'lab olsak, yaxshi bo'lar edi, lekin ayni paytda turli xil uslublarda qahva tayyorlash uchun etarlicha moslashuvchanlikni saqlasak. Javob ha, mumkin. Bu zavod usuli dizayn namunasi deb ataladi.

Oddiy zavoddan zavod usuliga

Muammoni iloji boricha samarali hal qilish uchun biz:
  1. Keling, usulni createCoffee(CoffeeType type)sinfga qaytaraylik CoffeeShop.
  2. Keling, bu usulni mavhum qilaylik.
  3. Sinfning o'zi CoffeeShopmavhum bo'ladi.
  4. Sinfning CoffeeShopmerosxo'rlari bo'ladi.
Ha, do'stim. Italiya qahvaxonasi italyan baristalarining eng yaxshi an'analariga muvofiq CoffeeShopuslubni amalga oshiradigan sinfning merosxo'ridan boshqa narsa emas . createCoffee(CoffeeType type)Shunday qilib, tartibda. 1-qadam. Keling, sinfni Coffeeabstrakt qilaylik. Hozir bizda turli xil mahsulotlarning ikkita oilasi bor. Italiya va Amerika kofe ichimliklar hali ham umumiy ajdodga ega: Coffee. Buni mavhum qilish to'g'ri bo'ladi:
public abstract class Coffee {
    public void makeCoffee(){
        // делаем кофе
    }
    public void pourIntoCup(){
        // наливаем в чашку
    }
}
CoffeeShopQadam 2. Mavhum usul bilan mavhum qilingcreateCoffee(CoffeeType type)
public abstract class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = createCoffee(type);

        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Вот ваш кофе! Спасибо, приходите еще!");
        return coffee;
    }

    protected abstract Coffee createCoffee(CoffeeType type);
}
Qadam 3. Mavhum qahvaxonaning avlodi bo'lgan italyan qahvaxonasini yarating. Unda biz createCoffee(CoffeeType type)italyan o'ziga xosligini hisobga olgan holda usulni amalga oshiramiz.
public class ItalianCoffeeShop extends CoffeeShop {

    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;
        switch (type) {
            case AMERICANO:
                coffee = new ItalianStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new ItalianStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new ItalianStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new ItalianStyleCaffeLatte();
                break;
        }
        return coffee;
    }
}
Qadam 4. Amerika uslubidagi qahvaxona uchun ham xuddi shunday qilaylik.
public class AmericanCoffeeShop extends CoffeeShop {
    @Override
    public Coffee createCoffee (CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new AmericanStyleAmericano();
                break;
            case ESPRESSO:
                coffee = new AmericanStyleEspresso();
                break;
            case CAPPUCCINO:
                coffee = new AmericanStyleCappuccino();
                break;
            case CAFFE_LATTE:
                coffee = new AmericanStyleCaffeLatte();
                break;
        }

        return coffee;
    }
}
5-qadam. Amerika va italyancha uslubdagi lattega buyurtma berish qanday bo'lishini ko'rib chiqamiz:
public class Main {
    public static void main(String[] args) {
        CoffeeShop italianCoffeeShop = new ItalianCoffeeShop();
        italianCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);

        CoffeeShop americanCoffeeShop = new AmericanCoffeeShop();
        americanCoffeeShop.orderCoffee(CoffeeType.CAFFE_LATTE);
    }
}
Seni tabriklayman. Biz qahvaxonamizda zavod uslubidagi dizayn namunasini joriy qildik.

Zavod usuli qanday ishlaydi

Endi biz nimani olganimizni batafsil ko'rib chiqaylik. Quyidagi diagrammada olingan sinflar ko'rsatilgan. Yashil bloklar yaratuvchi sinflari, ko'k bloklar mahsulot sinflari. Dizayn naqshlari: FactoryMethod - 2Qanday xulosalar chiqarish mumkin?
  1. Barcha mahsulotlar mavhum sinfning amalga oshirilishidir Coffee.
  2. Barcha yaratuvchilar mavhum sinfning amalga oshirilishidir CoffeeShop.
  3. Biz ikkita parallel sinf ierarxiyasini kuzatamiz:
    • Mahsulotlar ierarxiyasi. Biz Italiya avlodlarini va Amerika avlodlarini ko'ramiz
    • Ijodkorlar ierarxiyasi. Biz Italiya avlodlarini va Amerika avlodlarini ko'ramiz
  4. Superklassda qaysi maxsus mahsulotning amalga oshirilishi ( ) yaratilishi CoffeeShophaqida hech qanday ma'lumot yo'q .Coffee
  5. Superklass CoffeeShopma'lum bir mahsulotni yaratishni o'z avlodlariga topshiradi.
  6. Har bir avlod sinfi o'ziga xos xususiyatlarga muvofiq CoffeeShopzavod usulini amalga oshiradi . createCoffee()Boshqacha qilib aytganda, ijodkorlar sinflarini amalga oshirish doirasida yaratuvchilar sinfining o'ziga xos xususiyatlaridan kelib chiqqan holda ma'lum bir mahsulotni tayyorlash to'g'risida qaror qabul qilinadi.
Endi siz zavod usuli naqshini aniqlashga tayyormiz . Zavod usuli namunasi ob'ektni yaratish interfeysini belgilaydi, lekin pastki sinflarga yaratiladigan misol sinfini tanlash imkonini beradi. Shunday qilib, Factory usuli instantsiya operatsiyasini quyi sinflarga topshiradi. Umuman olganda, ta'rifni eslab qolish narsalar qanday ishlashini tushunish kabi muhim emas.

Zavod usuli tuzilishi

Dizayn naqshlari: FactoryMethod - 3Yuqoridagi diagrammada zavod usuli naqshining umumiy tuzilishi ko'rsatilgan. Bu erda yana nima muhim?
  1. Creator klassi zavod usulidan tashqari mahsulotlar bilan o'zaro ta'sir qiluvchi barcha usullarni amalga oshirishni o'z ichiga oladi.
  2. Mavhum usul factoryMethod()sinfning barcha avlodlari tomonidan amalga oshirilishi kerak Creator.
  3. Sinf mahsulotni bevosita ishlab chiqaradigan ConcreteCreatorusulni amalga oshiradi .factoryMethod()
  4. Bu sinf ma'lum mahsulotlarni yaratish uchun javobgardir. Bu ushbu mahsulotlarni yaratish haqida ma'lumotga ega bo'lgan yagona sinf.
  5. Barcha mahsulotlar umumiy interfeysni amalga oshirishi kerak - umumiy mahsulot sinfining avlodlari bo'lishi kerak. Bu mahsulotlardan foydalanadigan sinflar ular ustida aniq amalga oshirish emas, balki abstraktsiyalar darajasida ishlashi uchun zarurdir.

Uy vazifasi

Shunday qilib, bugun biz juda ko'p ish qildik va zavod usuli dizayn naqshini o'rgandik. Yopgan materialingizni birlashtirish vaqti keldi! Vazifa 1. Boshqa qahvaxona ochish ustida ishlang. U inglizcha yoki ispancha uslubda tayyorlanishi mumkin. Yoki hatto kosmik kema uslubida ham. Keling, qahvani porlashi uchun unga oziq-ovqat bo'yoqlarini qo'shamiz va umuman olganda, qahva shunchaki bo'sh joy bo'ladi! Vazifa 2. Oxirgi ma'ruzada sizda virtual sushi bar yoki virtual pitseriya yaratish vazifasi bor edi. Sizning vazifangiz bir joyda turish emas. Bugun siz muvaffaqiyatga erishish uchun zavod usuli namunasidan qanday foydalanishni bilib oldingiz. Ushbu bilimlardan foydalanish va o'z biznesingizni kengaytirish vaqti keldi;)
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION