JavaRush /Java Blogu /Random-AZ /Dizayn nümunələri: AbstractFactory

Dizayn nümunələri: AbstractFactory

Qrupda dərc edilmişdir
Salam! Bu gün biz dizayn nümunələrini öyrənməyə və abstrakt fabrik haqqında danışmağa davam edəcəyik . Dizayn nümunələri: AbstractFactory - 1Mühazirə zamanı nə edəcəyik:
  • Gəlin mücərrəd fabrikin nə olduğunu və bu nümunənin hansı problemi həll etdiyini müzakirə edək;
  • istifadəçi interfeysi ilə qəhvə sifariş etmək üçün çarpaz platforma tətbiqi çərçivəsini yaradacağıq;
  • Bu nümunəni diaqram və kodla istifadə etmək üçün təlimatları öyrənək;
  • Bonus olaraq, mühazirədə gizli bir Pasxa yumurtası var, bunun sayəsində Java-dan istifadə edərək əməliyyat sisteminin adını təyin etməyi öyrənəcək və nəticədən asılı olaraq bu və ya digər hərəkətləri yerinə yetirəcəksiniz.
Bu nümunəni tam başa düşmək üçün aşağıdakı mövzuları yaxşı başa düşməlisiniz:
  • Java-da miras;
  • Java-da abstrakt siniflər və metodlar.

Abstrakt fabrik nümunəsi hansı problemləri həll edir?

Abstrakt fabrik, bütün fabrik nümunələri kimi, bizə yeni obyektlərin yaradılmasını düzgün təşkil etməyə kömək edir. Onun köməyi ilə biz bir-biri ilə əlaqəli obyektlərin müxtəlif ailələrinin "buraxılmasını" idarə edirik. Bir-biri ilə əlaqəli obyektlərin müxtəlif ailələri...Bu nədir? Narahat olmayın: praktikada hər şey göründüyündən daha sadədir. Başlayaq əlaqəli obyektlər ailəsi nə ola bilər? Tutaq ki, siz və mən bir strategiya hazırlayırıq və orada bir neçə döyüş bölməsi var:
  • piyada;
  • süvari;
  • oxatanlar.
Bu tip döyüş hissələri bir-biri ilə əlaqəlidir, çünki eyni orduda xidmət edirlər. Deyə bilərik ki, yuxarıda sadalanan kateqoriyalar bir-biri ilə əlaqəli obyektlər ailəsidir. Bu sıralanır. Lakin mücərrəd fabrik nümunəsi bir- biri ilə əlaqəli obyektlərin müxtəlif ailələrinin yaradılmasını təşkil etmək üçün istifadə olunur . Burada da mürəkkəb heç nə yoxdur. Məsələni strategiya ilə davam etdirək. Onların adətən bir neçə fərqli qarşı tərəfi olur. Fərqli tərəflərin döyüş hissələri görünüş baxımından əhəmiyyətli dərəcədə fərqlənə bilər. Roma ordusunun piyadaları, süvariləri və oxatanları Vikinqlərin piyadaları, atlıları və oxatanları ilə eyni deyil. Strategiya çərçivəsində müxtəlif orduların əsgərləri bir-biri ilə əlaqəli obyektlərin müxtəlif ailələridir. Bir proqramçının səhvi ilə Napoleon dövründən qalma fransız geyimində, tüfəngi hazır olan bir əsgər Roma piyadaları arasında gəzirdisə, gülməli olardı. Məhz belə bir problemi həll etmək üçün mücərrəd fabrik dizayn nümunəsinə ehtiyac var. Xeyr, zaman səyahətinin xəcalət çəkməsi problemləri deyil, bir-biri ilə əlaqəli obyektlərin müxtəlif qruplarının yaradılması. Mücərrəd fabrik bütün mövcud məhsulları (ailə obyektləri) yaratmaq üçün interfeys təqdim edir. Mücərrəd bir fabrik adətən bir neçə tətbiqə malikdir. Onların hər biri varyasyonlardan birinin məhsullarını yaratmaqdan məsuldur. Strategiyanın bir hissəsi olaraq, mücərrəd piyada, oxatan və süvari yaradan mücərrəd fabrikimiz, eləcə də bu fabrikin tətbiqləri olardı. Roma legionerlərini yaradan fabrik və məsələn, Karfagen döyüşçülərini yaradan fabrik. Abstraksiya bu nümunənin ən mühüm prinsipidir. Zavod müştəriləri onunla və məhsullarla yalnız abstrakt interfeyslər vasitəsilə işləyirlər. Buna görə də, hazırda hansı döyüşçülər yaratdığımızı düşünmək məcburiyyətində deyilik, lakin bu məsuliyyəti mücərrəd fabrikin müəyyən bir tətbiqinə köçürük.

Qəhvəxananı avtomatlaşdırmağa davam edirik

Son mühazirədə biz fabrik üsulu nümunəsini öyrəndik, onun köməyi ilə qəhvə biznesini genişləndirə və bir neçə yeni qəhvə satış nöqtəsi aça bildik. Bu gün biz işimizi müasirləşdirmək üçün işimizi davam etdirəcəyik. Mücərrəd fabrik nümunəsindən istifadə edərək, qəhvə onlayn sifariş etmək üçün yeni bir masa üstü tətbiqinin əsasını qoyacağıq. İş masası üçün ərizə yazarkən biz həmişə cross-platform haqqında düşünməliyik. Tətbiqimiz həm macOS, həm də Windows-da işləməlidir (spoiler: Linux sizə ev tapşırığı olaraq qalacaq). Tətbiqimiz necə görünəcək? Olduqca sadə: bu, mətn sahəsindən, seçim sahəsindən və düymədən ibarət forma olacaq. Fərqli əməliyyat sistemlərindən istifadə təcrübəniz varsa, Windows-da düymələrin Mac-dan fərqli olaraq göstərildiyini mütləq fərq etdiniz. Hər şey kimi... Elə isə başlayaq. Məhsul ailələrinin rolunda, yəqin ki, artıq başa düşdüyünüz kimi, qrafik interfeys elementlərimiz olacaq:
  • düymələr;
  • mətn sahələri;
  • seçim üçün sahələr.
İmtina. onClickHər bir interfeys daxilində biz və onValueChangedya kimi üsulları müəyyən edə bilərik onInputChanged. Bunlar. müxtəlif hadisələri idarə etməyə imkan verəcək üsullar (düyməni sıxmaq, mətn daxil etmək, seçim qutusunda dəyər seçmək). Bütün bunlar nümunəni çox yükləməmək və fabrik nümunəsini öyrənmək üçün daha əyani etmək üçün qəsdən buraxılmışdır. Məhsullarımız üçün abstrakt interfeysləri müəyyən edək:
public interface Button {}
public interface Select {}
public interface TextField {}
Hər bir əməliyyat sistemi üçün biz həmin əməliyyat sisteminin üslubunda interfeys elementləri yaratmalıyıq. Windows və MacOS üçün yazırıq. Windows üçün tətbiqlər yaradaq:
public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
İndi MacOS üçün eyni:
public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
Əla. İndi bütün mövcud mücərrəd məhsul növlərini yaradacaq abstrakt fabrikimizə başlaya bilərik:
public interface GUIFactory {

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

}
Mükəmməl. Gördüyünüz kimi, indiyə qədər mürəkkəb bir şey yoxdur. Sonra hər şey sadədir. Məhsullara bənzətməklə, biz hər bir OS üçün fabrikimizin müxtəlif tətbiqlərini yaradırıq. Windows ilə başlayaq:
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();
    }
}
Onun necə işlədiyini daha da nümayiş etdirmək üçün metodlar və konstruktorlar daxilində konsol çıxışı əlavə edilmişdir. İndi macOS üçün:
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();
    }
}
Qeyd: hər bir metod öz imzasına görə mücərrəd tip qaytarır. Ancaq metodun içərisində biz məhsulun konkret icrasını yaradırıq. Bu, konkret nümunələrin yaradılmasına nəzarət etdiyimiz yeganə yerdir. İndi forma sinfini yazmağın vaxtı gəldi. Bu, sahələri interfeys elementləri olan Java sinfidir:
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();
    }
}
Abstrakt zavod interfeys elementlərini yaradan forma konstruktoruna ötürülür. Müəyyən bir OS üçün interfeys elementləri yarada bilməmiz üçün tələb olunan zavod tətbiqini konstruktora ötürəcəyik.
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();
    }
}
Proqramı Windows-da işə salsaq, aşağıdakı nəticəni alacağıq:

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 çıxış aşağıdakı kimi olacaq:

Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
Linux-da:

Unknown OS, can't draw form :( 
Yaxşı, siz və mən aşağıdakı nəticəyə gəlirik. Biz verilmiş OS üçün uyğun olan interfeys elementlərini yaradan GUI tətbiqi üçün çərçivə yazdıq. Yaratdıqlarımızı qısaca təkrarlayaq:
  • Məhsul ailəsi: giriş sahəsi, seçim sahəsi və düymə.
  • Windows və macOS üçün bu məhsullar ailəsinin müxtəlif tətbiqləri.
  • Məhsullarımızı yaratmaq üçün interfeysi müəyyən etdiyimiz abstrakt fabrik.
  • Fabrikimizin iki tətbiqi, hər biri müəyyən bir məhsul ailəsi yaratmaqdan məsuldur.
  • Sahələri abstrakt fabrikdən istifadə edərək tələb olunan dəyərlərlə konstruktorda işə salınan mücərrəd interfeys elementləri olan forma, Java sinfi.
  • Tətbiq sinfi. Onun içərisində fabrikimizin tələb olunan icrasını konstruktora ötürəcəyimiz bir forma yaradırıq.
Cəmi: biz abstrakt fabrik nümunəsini həyata keçirdik.

Abstract Fabrika: istifadə üçün təlimat

Abstract Factory, xüsusi məhsul siniflərinə bağlı olmadan müxtəlif məhsul ailələrinin yaradılmasını idarə etmək üçün dizayn nümunəsidir. Bu şablondan istifadə edərkən aşağıdakıları etməlisiniz:
  1. Məhsul ailələrini özləri müəyyənləşdirin. Tutaq ki, onlardan ikimiz var:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. Ailə daxilindəki hər bir məhsul üçün mücərrəd sinif (interfeys) təyin edin. Bizim vəziyyətimizdə belədir:
    • ProductA
    • ProductB
  3. Hər bir məhsul ailəsində hər bir məhsul 2-ci addımda müəyyən edilmiş interfeysi həyata keçirməlidir.
  4. 2-ci addımda müəyyən edilmiş hər bir məhsul üçün yaratmaq üsulları ilə mücərrəd fabrik yaradın. Bizim vəziyyətimizdə bu üsullar olacaq:
    • ProductA createProductA();
    • ProductB createProductB();
  5. Abstrakt fabrikin tətbiqlərini yaradın ki, hər bir tətbiq eyni ailənin məhsullarının yaradılmasına nəzarət etsin. Bunun üçün mücərrəd fabrikin hər bir tətbiqi daxilində bütün yaratma üsullarını həyata keçirmək lazımdır ki, məhsulların konkret tətbiqləri yaradılsın və onların içərisinə qaytarılsın.
Aşağıda yuxarıda təsvir olunan təlimatları əks etdirən UML diaqramı verilmişdir: Dizayn nümunələri: AbstractFactory - 3İndi bu təlimatın kodunu yazaq:
// Определим общие интерфейсы продуктов
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();
    }
}

Ev tapşırığı

Materialı birləşdirmək üçün 2 şeyi edə bilərsiniz:
  1. Kofe sifarişi proqramını təkmilləşdirin ki, o, Linux-da işləsin.
  2. İstənilən strategiyanın vahidlərini istehsal etmək üçün öz mücərrəd fabrikinizi yaradın. Bu ya həqiqi ordularla tarixi strategiya, ya da orklar, cırtdanlar və elflərlə fantaziya ola bilər. Əsas odur ki, sizə maraqlı gəlir. Yaradıcı olun, konsola sancaqlar yerləşdirin və naxışları öyrənərək əylənin!
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION