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

Dizayn naqshlari: AbstractFactory

Guruhda nashr etilgan
Salom! Bugun biz dizayn naqshlarini o'rganishni davom ettiramiz va mavhum zavod haqida gapiramiz . Dizayn naqshlari: AbstractFactory - 1Ma'ruza davomida nima qilamiz:
  • Keling, mavhum zavod nima ekanligini va bu naqsh qanday muammoni hal qilishini muhokama qilaylik;
  • biz foydalanuvchi interfeysi bilan qahva buyurtma qilish uchun o'zaro faoliyat platforma ilovasining asosini yaratamiz;
  • Keling, ushbu naqshni diagramma va kod bilan ishlatish bo'yicha ko'rsatmalarni o'rganamiz;
  • Bonus sifatida ma'ruzada Pasxa tuxumi yashiringan, buning yordamida siz Java-dan foydalangan holda operatsion tizim nomini aniqlashni o'rganasiz va natijaga qarab u yoki bu amalni bajarasiz.
Ushbu naqshni to'liq tushunish uchun siz quyidagi mavzularni yaxshi tushunishingiz kerak:
  • Java-da meros;
  • Java tilidagi abstrakt sinflar va usullar.

Mavhum zavod namunasi qanday muammolarni hal qiladi?

Abstrakt zavod, barcha zavod naqshlari singari, bizga yangi ob'ektlarni yaratishni to'g'ri tashkil etishga yordam beradi. Uning yordami bilan biz bir-biriga bog'langan ob'ektlarning turli oilalarini "bo'shatish" ni boshqaramiz. O'zaro bog'langan ob'ektlarning turli oilalari ... Bu nima? Xavotir olmang: amalda hamma narsa tuyulishi mumkin bo'lgandan ham oddiyroq. Keling, o'zaro bog'liq ob'ektlar oilasi nima bo'lishi mumkinligidan boshlaylik? Aytaylik, biz siz bilan strategiya ishlab chiqmoqdamiz va unda bir nechta jangovar bo'linmalar mavjud:
  • piyoda askarlar;
  • otliq askar;
  • kamonchilar.
Ushbu turdagi jangovar qismlar bir-biri bilan bog'liq, chunki ular bir xil armiyada xizmat qiladi. Aytishimiz mumkinki, yuqorida sanab o'tilgan kategoriyalar o'zaro bog'liq bo'lgan ob'ektlar oilasidir. Bu tartibga solingan. Lekin mavhum zavod namunasi bir-biriga bog'langan ob'ektlarning turli oilalarini yaratishni tashkil qilish uchun ishlatiladi . Bu erda ham murakkab narsa yo'q. Keling, misolni strategiya bilan davom ettiramiz. Ular odatda bir nechta qarama-qarshi tomonlarga ega. Turli tomonlarning jangovar bo'linmalari tashqi ko'rinishida sezilarli darajada farq qilishi mumkin. Rim armiyasining piyoda askarlari, otliqlari va kamonchilari Vikinglarning piyoda askarlari, otliqlari va kamonchilari bilan bir xil emas. Strategiya doirasida turli qo'shinlarning askarlari bir-biriga bog'langan ob'ektlarning turli oilalaridir. Agar dasturchi xatosi bilan Napoleon davridagi frantsuz kiyimidagi, mushketi tayyor bo'lgan askar Rim piyodalari orasida aylanib yursa, kulgili bo'lar edi. Bunday muammoni hal qilish uchun mavhum zavod dizayni namunasi kerak. Yo'q, vaqt sayohati sharmandalik muammolari emas, balki bir-biriga bog'langan ob'ektlarning turli guruhlarini yaratish. Mavhum zavod barcha mavjud mahsulotlarni (oilaviy ob'ektlarni) yaratish uchun interfeysni taqdim etadi. Mavhum zavod odatda bir nechta ilovalarga ega. Ularning har biri o'zgarishlardan birining mahsulotlarini yaratish uchun javobgardir. Strategiyaning bir qismi sifatida bizda mavhum piyodalar, kamonchilar va otliq qo'shinlarni yaratadigan mavhum zavod, shuningdek, ushbu zavodning amalga oshirilishi bo'ladi. Rim legionerlarini yaratadigan zavod va, masalan, Karfagen jangchilarini yaratadigan zavod. Abstraktsiya bu naqshning eng muhim tamoyilidir. Zavod mijozlari u bilan va mahsulotlar bilan faqat mavhum interfeyslar orqali ishlaydi. Shuning uchun, biz hozirda qanday jangchilarni yaratayotganimiz haqida o'ylamasligimiz kerak, lekin bu mas'uliyatni mavhum zavodning muayyan amalga oshirilishiga o'tkazamiz.

Biz qahvaxonani avtomatlashtirishda davom etamiz

Oxirgi ma'ruzada biz zavod usuli namunasini o'rganib chiqdik, uning yordamida biz qahva biznesini kengaytira oldik va bir nechta yangi kofe savdo nuqtalarini ochdik. Bugun biz biznesimizni modernizatsiya qilish bo'yicha ishimizni davom ettiramiz. Mavhum zavod naqshidan foydalanib, biz Internetda qahva buyurtma qilish uchun yangi ish stoli ilovasi uchun poydevor qo'yamiz. Ish stoli uchun dastur yozganimizda, biz doimo o'zaro faoliyat platformalar haqida o'ylashimiz kerak. Ilovamiz macOS va Windows operatsion tizimida ishlashi kerak (spoiler: Linux sizga uy vazifasi sifatida qoldiriladi). Bizning arizamiz qanday ko'rinishga ega bo'ladi? Juda oddiy: bu matn maydoni, tanlash maydoni va tugmadan iborat shakl bo'ladi. Agar siz turli xil operatsion tizimlardan foydalanish tajribangiz bo'lsa, Windows-da tugmalar Mac-ga qaraganda boshqacha ko'rsatilishini aniq payqadingiz. Hammasi kabi... Shunday ekan, boshlaylik. Mahsulot oilalari rolida, siz allaqachon tushunganingizdek, biz grafik interfeys elementlariga ega bo'lamiz:
  • tugmalar;
  • matn maydonlari;
  • tanlash uchun maydonlar.
Rad etish. onClickHar bir interfeys ichida biz yoki onValueChangedkabi usullarni belgilashimiz mumkin onInputChanged. Bular. turli hodisalarni boshqarishga imkon beradigan usullar (tugmani bosish, matn kiritish, tanlash maydonida qiymat tanlash). Bularning barchasi misolni ortiqcha yuklamaslik va zavod naqshini o'rganish uchun ko'proq ingl. Mahsulotlarimiz uchun mavhum interfeyslarni aniqlaymiz:
public interface Button {}
public interface Select {}
public interface TextField {}
Har bir operatsion tizim uchun biz ushbu operatsion tizim uslubida interfeys elementlarini yaratishimiz kerak. Biz Windows va MacOS uchun yozamiz. Windows uchun ilovalar yarataylik:
public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
Endi MacOS uchun ham xuddi shunday:
public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
Ajoyib. Endi biz barcha mavjud mavhum mahsulot turlarini yaratadigan mavhum fabrikamizni ishga tushirishimiz mumkin:
public interface GUIFactory {

    Button createButton();
    TextField createTextField();
    Select createSelect();

}
Mukammal. Ko'rib turganingizdek, hozircha hech qanday murakkab narsa yo'q. Keyin hamma narsa xuddi shunday oddiy. Mahsulotlarga o'xshab, biz har bir OT uchun fabrikamizning turli xil ilovalarini yaratamiz. Windows bilan boshlaylik:
public class WindowsGUIFactory implements GUIFactory {
    public WindowsGUIFactory() {
        System.out.println("Creating gui factory for Windows OS");
    }

    public Button createButton() {
        System.out.println("Creating Button for Windows OS");
        return new WindowsButton();
    }

    public TextField createTextField() {
        System.out.println("Creating TextField for Windows OS");
        return new WindowsTextField();
    }

    public Select createSelect() {
        System.out.println("Creating Select for Windows OS");
        return new WindowsSelect();
    }
}
Usullar va konstruktorlar ichidagi konsol chiqishi uning qanday ishlashini yanada ko'rsatish uchun qo'shildi. Endi macOS uchun:
public class MacGUIFactory implements GUIFactory {
    public MacGUIFactory() {
        System.out.println("Creating gui factory for macOS");
    }

    @Override
    public Button createButton() {
        System.out.println("Creating Button for macOS");
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        System.out.println("Creating TextField for macOS");
        return new MacTextField();
    }

    @Override
    public Select createSelect() {
        System.out.println("Creating Select for macOS");
        return new MacSelect();
    }
}
Eslatma: har bir usul o'z imzosiga ko'ra mavhum turni qaytaradi. Ammo usul ichida biz mahsulotning aniq amalga oshirilishini yaratamiz. Bu biz aniq misollarni yaratishni nazorat qiladigan yagona joy. Endi forma sinfini yozish vaqti keldi. Bu Java klassi, uning maydonlari interfeys elementlari:
public class OrderCoffeeForm {
    private final TextField customerNameTextField;
    private final Select coffeTypeSelect;
    private final Button orderButton;

    public OrderCoffeeForm(GUIFactory factory) {
        System.out.println("Creating order coffee form");
        customerNameTextField = factory.createTextField();
        coffeTypeSelect = factory.createSelect();
        orderButton = factory.createButton();
    }
}
Interfeys elementlarini yaratuvchi forma konstruktoriga mavhum zavod uzatiladi. Muayyan OS uchun interfeys elementlarini yaratishimiz uchun biz kerakli zavodni konstruktorga o'tkazamiz.
public class Application {
    private OrderCoffeeForm orderCoffeeForm;

    public void drawOrderCoffeeForm() {
        // Определим Name операционной системы, получив meaning системной проперти через System.getProperty
        String osName = System.getProperty("os.name").toLowerCase();
        GUIFactory guiFactory;

        if (osName.startsWith("win")) { // Для windows
            guiFactory = new WindowsGUIFactory();
        } else if (osName.startsWith("mac")) { // Для mac
            guiFactory = new MacGUIFactory();
        } else {
            System.out.println("Unknown OS, can't draw form :( ");
            return;
        }
        orderCoffeeForm = new OrderCoffeeForm(guiFactory);
    }

    public static void main(String[] args) {
        Application application = new Application();
        application.drawOrderCoffeeForm();
    }
}
Agar biz dasturni Windows da ishga tushirsak, quyidagi natijani olamiz:

Creating gui factory for Windows OS
Creating order coffee form
Creating TextField for Windows OS
Creating Select for Windows OS
Creating Button for Windows OS
Mac-da chiqish quyidagicha bo'ladi:

Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
Linuxda:

Unknown OS, can't draw form :( 
Xo'sh, siz va men quyidagi xulosaga kelamiz. Biz ma'lum bir OS uchun mos bo'lgan interfeys elementlarini yaratadigan GUI ilovasi uchun ramka yozdik. Keling, yaratganimizni qisqacha takrorlaymiz:
  • Mahsulotlar oilasi: kiritish maydoni, tanlash maydoni va tugma.
  • Windows va macOS uchun ushbu mahsulotlar oilasining turli ilovalari.
  • Biz mahsulotimizni yaratish interfeysini aniqlagan mavhum zavod.
  • Bizning fabrikamizning ikkita ilovasi, ularning har biri ma'lum bir mahsulot oilasini yaratish uchun javobgardir.
  • Shakl, Java klassi, uning maydonlari mavhum zavod yordamida kerakli qiymatlar bilan konstruktorda ishga tushirilgan mavhum interfeys elementlari.
  • Ilova sinfi. Uning ichida biz konstruktorga fabrikamizning kerakli bajarilishini o'tkazadigan shakl yaratamiz.
Jami: biz mavhum zavod naqshini amalga oshirdik.

Mavhum fabrika: foydalanish bo'yicha ko'rsatmalar

Mavhum fabrika - bu muayyan mahsulot sinflariga bog'lanmagan holda turli xil mahsulot oilalarini yaratishni boshqarish uchun dizayn namunasidir. Ushbu shablondan foydalanganda siz:
  1. Mahsulot oilalarini o'zlari aniqlang. Faraz qilaylik, bizda ulardan ikkitasi bor:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. Oila ichidagi har bir mahsulot uchun mavhum sinfni (interfeys) belgilang. Bizning holatlarimizda bu:
    • ProductA
    • ProductB
  3. Har bir mahsulot oilasida har bir mahsulot 2-bosqichda belgilangan interfeysni amalga oshirishi kerak.
  4. 2-bosqichda belgilangan har bir mahsulot uchun yaratish usullari bilan mavhum zavod yarating. Bizning holatlarimizda bu usullar quyidagilar bo'ladi:
    • ProductA createProductA();
    • ProductB createProductB();
  5. Mavhum zavodning ilovalarini yarating, shunda har bir dastur bitta oilaning mahsulotlarini yaratishni nazorat qiladi. Buning uchun mavhum zavodning har bir amalga oshirilishi ichida barcha yaratish usullarini amalga oshirish kerak, shunda mahsulotlarning aniq amalga oshirilishi yaratiladi va ular ichida qaytariladi.
Quyida yuqorida tavsiflangan ko'rsatmalarni aks ettiruvchi UML diagrammasi keltirilgan: Dizayn naqshlari: AbstractFactory - 3Endi ushbu ko'rsatma uchun kodni yozamiz:
// Определим общие интерфейсы продуктов
public interface ProductA {}
public interface ProductB {}

// Создадим различные реализации (семейства) наших продуктов
public class SpecificProductA1 implements ProductA {}
public class SpecificProductB1 implements ProductB {}

public class SpecificProductA2 implements ProductA {}
public class SpecificProductB2 implements ProductB {}

// Создадим абстрактную фабрику
public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory1 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new SpecificProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new SpecificProductB1();
    }
}

// Создадим реализацию абстрактной фабрики для создания продуктов семейства 1
public class SpecificFactory2 implements AbstractFactory {

    @Override
    public ProductA createProductA() {
        return new SpecificProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new SpecificProductB2();
    }
}

Uy vazifasi

Materialni birlashtirish uchun siz ikkita narsani qilishingiz mumkin:
  1. Kofe buyurtma berish ilovasini Linuxda ishlashi uchun yaxshilang.
  2. Har qanday strategiyaning birliklarini ishlab chiqarish uchun o'zingizning mavhum fabrikangizni yarating. Bu haqiqiy qo'shinlar bilan tarixiy strategiya yoki orklar, mittilar va elflar bilan bo'lgan fantaziya bo'lishi mumkin. Asosiysi, bu sizga qiziq. Ijodkor bo'ling, konsolga pinlar joylang va naqshlarni o'rganing!
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION