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 . Mü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.
- 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.
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.
onClick
Hər bir interfeys daxilində biz və onValueChanged
ya 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.
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:- Məhsul ailələrini özləri müəyyənləşdirin. Tutaq ki, onlardan ikimiz var:
SpecificProductA1
,SpecificProductB1
SpecificProductA2
,SpecificProductB2
- 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
- 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.
- 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();
- 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.
// Определим общие интерфейсы продуктов
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:- Kofe sifarişi proqramını təkmilləşdirin ki, o, Linux-da işləsin.
- İ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!
GO TO FULL VERSION