JavaRush /Java блогу /Random-KY /Дизайн үлгүлөрү: AbstractFactory

Дизайн үлгүлөрү: AbstractFactory

Группада жарыяланган
Салам! Бүгүн биз дизайн үлгүлөрүн изилдөөнү улантабыз жана абстракттуу фабрика жөнүндө сүйлөшөбүз . Дизайн үлгүлөрү: AbstractFactory - 1Лекция учурунда эмне кылабыз:
  • Келгиле, абстракттуу фабрика деген эмне экенин жана бул үлгү кандай маселени чечерин талкуулайлы;
  • биз колдонуучу интерфейси менен кофеге заказ кылуу үчүн платформалар аралык тиркеменин негизин түзөбүз;
  • Диаграмма жана code менен бул үлгүнү колдонуу боюнча нускамаларды изилдеп көрөлү;
  • Бонус катары лекцияда Пасха жумурткасы катылган, анын аркасында Java аркылуу операциялык системанын атын аныктоону жана натыйжага жараша тигил же бул аракетти аткарууну үйрөнөсүз.
Бул үлгүнү толук түшүнүү үчүн, сиз төмөнкү темаларды жакшы түшүнүшүңүз керек:
  • Java боюнча мурас;
  • абстракттуу класстар жана Java ыкмалары.

Абстракттуу фабрика үлгүсү кандай маселелерди чечет?

Абстракттуу фабрика бардык фабрикалык улгулер сыяктуу эле бизге жацы an objectилерди тузууну туура уюштурууга жардам берет. Анын жардамы менен биз бири-бири менен байланышкан an objectтердин ар кандай үй-бүлөлөрүн "чыгарууну" башкарабыз. Өз ара байланышкан an objectтердин ар кандай үй-бүлөлөрү...Бул эмне? Кабатыр болбоңуз: иш жүзүндө баары көрүнгөндөн жөнөкөй. Келгиле, байланыштуу an objectтердин үй-бүлөсү эмне болушу мүмкүн менен баштайлы? Сиз экөөбүз стратегия иштеп жатабыз дейли, анда бир нече согуштук бөлүмдөр бар:
  • жөө аскерлер;
  • атчан аскерлер;
  • жаачылар.
Күжүрмөн бөлүктөрдүн бул түрлөрү бири-бири менен байланыштуу, анткени алар бир армияда кызмат өтөшөт. Жогоруда саналган категориялар өз ара байланышкан an objectтердин үй-бүлөсү деп айта алабыз. Ошол чечилди. Бирок абстракттуу фабрика үлгүсү бири-бири менен байланышкан an objectтердин ар кандай үй-бүлөлөрүн түзүүнү уюштуруу үчүн колдонулат . Бул жерде да татаал эч нерсе жок. Келгиле, мисалды стратегия менен уланталы. Алар, адатта, бир нече ар кандай карама-каршы жактары бар. Ар кандай тараптардын согуштук бөлүктөрү сырткы көрүнүшү боюнча бир топ айырмаланышы мүмкүн. Рим армиясынын жөө аскерлери, атчандары жана жаачылары викингдердин жөө аскерлери, атчандары жана жаачылары менен бирдей эмес. Стратегиянын алкагында, ар кандай армиялардын жоокерлери бири-бири менен байланышкан an objectилердин ар кандай үй-бүлөлөрү болуп саналат. Эгерде программисттин катасы менен Наполеондун убагындагы француз формасын кийген жоокер римдик жөө аскерлердин арасында мушкети даяр болсо, күлкүлүү болмок. Мына ушундай маселени чечуу учун абстракттуу фабриканын конструкциясы керек. Жок, убакыт саякатынын уят проблемалары эмес, бири-бири менен байланышкан an objectтердин ар кандай топторун түзүү. Абстракттуу фабрика бардык иштеп жаткан өнүмдөрдү (үй-бүлөлүк an objectилерди) түзүү үчүн интерфейсти камсыз кылат. Абстракттуу фабрика, адатта, бир нече ишке кирет. Алардын ар бири вариациялардын биринин өнүмдөрүн түзүү үчүн жооптуу. Стратегиянын бир бөлүгү катары бизде абстрактуу жөө аскерлерди, жаачыларды жана атчан аскерлерди түзгөн абстракттуу фабрика, ошондой эле бул фабриканын ишке ашырылышы болмок. Римдик легионерлерди жараткан завод жана, мисалы, Карфагендик жоокерлерди жараткан фабрика. Абстракция бул калыптын эң маанилүү принциби. Заводдун кардарлары аны менен жана продуктылар менен абстракттуу интерфейстер аркылуу гана иштешет. Ошондуктан, биз азыр кандай жоокерлерди жаратып жаткандыгыбыз женунде ойлонуунун кажети жок, бирок бул жоопкерчorкти абстракттуу фабриканын кандайдыр бир конкреттуу ишке ашыруусуна которуу керек.

Биз кофекананы автоматташтырууну улантып жатабыз

Акыркы лекцияда биз фабрикалык ыкманы үйрөндүк, анын жардамы менен кофе бизнесин кеңейтип, бир нече жаңы кофе сатуу пункттарын ача алдык. Бүгүн биз бизнесибизди модернизациялоо боюнча ишибизди улантабыз. Заводдун абстракттуу үлгүсүн колдонуп, биз кофеге онлайн заказ кылуу үчүн жаңы рабочий тиркеменин пайдубалын түптөйбүз. Иш тактасына арыз жазганда, биз ар дайым кросс-платформа жөнүндө ойлонушубуз керек. Биздин тиркеме macOS да, Windows да иштеши керек (спойлер: Linux сизге үй тапшырмасы катары калтырылат). Биздин колдонмо кандай болот? Абдан жөнөкөй: бул текст талаасынан, тандоо талаасынан жана баскычтан турган форма болот. Эгерде сизде ар кандай операциялык системаларды колдонуу тажрыйбаңыз бар болсо, анда Windows'до баскычтар Macтагыдан башкача көрсөтүлөрүн байкадыңыз. Башкалардай эле... Анда эмесе, баштайлы. Продукт үй-бүлөлөрүнүн ролунда, сиз түшүнгөнүңүздөй, бизде графикалык интерфейс элементтери болот:
  • баскычтар;
  • текст талаалары;
  • тандоо үчүн талаалар.
Жоопкерчorктен баш тартуу. onClickАр бир интерфейстин ичинде , onValueChangedже сыяктуу ыкмаларды аныктай алабыз onInputChanged. Ошол. ар кандай окуяларды башкарууга мүмкүндүк берүүчү ыкмалар (баскычты чыкылdateу, текст киргизүү, тандоо кутучасында маанини тандоо). Мунун баары мисалды ашыкча жүктөбөш үчүн жана заводдун үлгүсүн үйрөнүү үчүн аны визуалдуу кылуу үчүн атайылап кетирилген. Биздин продуктылар үчүн абстракттуу интерфейстерди аныктайлы:
public interface Button {}
public interface Select {}
public interface TextField {}
Ар бир операциялык система үчүн биз ошол операциялык системанын стorнде интерфейстин элементтерин түзүшүбүз керек. Биз Windows жана MacOS үчүн жазабыз. Келгиле, Windows үчүн ишке ашырууларды түзөлү:
public class WindowsButton implements Button {
}

public class WindowsSelect implements Select {
}

public class WindowsTextField implements TextField {
}
Эми MacOS үчүн да:
public class MacButton implements Button {
}

public class MacSelect implements Select {
}

public class MacTextField implements TextField {
}
Абдан жакшы. Эми биз абстракттуу фабрикабызды баштай алабыз, ал бардык абстрактуу продукциянын түрлөрүн түзөт:
public interface GUIFactory {

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

}
Мыкты. Көрүнүп тургандай, азырынча татаал эч нерсе жок. Ошондо баары эле жөнөкөй. Продукцияларга окшоштуруп, биз ар бир ОС үчүн фабрикабыздын ар кандай ишке ашырууларын түзөбүз. Windows менен баштайлы:
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();
    }
}
Методдордун жана конструкторлордун ичиндеги консолдук чыгарылыш анын кантип иштээрин көрсөтүү үчүн кошулду. Азыр macOS үчүн:
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();
    }
}
Эскертүү: ар бир ыкма өзүнүн кол тамгасына ылайык абстракттуу түрүн кайтарат. Бирок методдун ичинде биз буюмдун конкреттүү ишке ашырылышын түзөбүз. Бул биз конкреттүү инстанцияларды түзүүнү көзөмөлдөй турган жалгыз жер. Эми форма классын жазууга убакыт келди. Бул Java классы, анын талаалары интерфейс элементтери:
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();
    }
}
Абстракттуу фабрика форма конструкторуна өткөрүлүп берилет, ал интерфейстин элементтерин түзөт. Белгилүү бир ОС үчүн интерфейстин элементтерин түзө алышыбыз үчүн, биз керектүү заводдук ишке ашырууну конструкторго өткөрүп беребиз.
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();
    }
}
Эгерде биз тиркемени Windowsта иштетсек, биз төмөнкү натыйжаны алабыз:

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та чыгаруу төмөнкүдөй болот:

Creating gui factory for macOS
Creating order coffee form
Creating TextField for macOS
Creating Select for macOS
Creating Button for macOS
Linux боюнча:

Unknown OS, can't draw form :( 
Ооба, сен экөөбүз төмөнкүдөй жыйынтык чыгарабыз. Биз GUI тиркемесинин негизин жаздык, ал так ошол ОС үчүн ылайыктуу интерфейстин элементтерин түзөт. Биз жараткан нерсени кыскача кайталайлы:
  • Продукт үй-бүлөсү: киргизүү талаасы, тандоо талаасы жана баскыч.
  • Windows жана macOS үчүн бул өнүмдөрдүн ар кандай ишке ашырылышы.
  • Абстракттуу фабрика, анын ичинде биз өнүмдөрдү түзүү үчүн интерфейсти аныктадык.
  • Биздин фабриканын эки ишке ашыруу, алардын ар бири буюмдардын белгилүү бир үй-бүлө түзүү үчүн жооптуу.
  • Форма, Java классы, анын талаалары абстракттуу фабриканын жардамы менен керектүү маанилер менен конструктордо инициализацияланган абстрактуу интерфейс элементтери.
  • Колдонмо классы. Анын ичинде биз конструкторго заводубуздун талап кылынган аткарылышын тапшырган форманы түзөбүз.
Бардыгы: биз абстракттуу фабрика үлгүсүн ишке ашырдык.

Реферат Фабрика: колдонуу боюнча нускама

Абстракттуу фабрика - бул белгилүү бир продукт класстарына байланбастан ар кандай продукт үй-бүлөлөрүн түзүүнү башкаруу үчүн дизайн үлгүсү. Бул шаблонду колдонууда, сиз керек:
  1. Продукт үй-бүлөлөрүн өздөрү аныктаңыз. Бизде алардын экөөсү бар дейли:
    • SpecificProductA1,SpecificProductB1
    • SpecificProductA2,SpecificProductB2
  2. Үй-бүлө ичиндеги ар бир продукт үчүн абстракттуу классты (интерфейс) аныктаңыз. Биздин учурда бул:
    • ProductA
    • ProductB
  3. Ар бир продукт үй-бүлөсүндө ар бир продукт 2-кадамда аныкталган интерфейсти ишке ашырууга тийиш.
  4. 2-кадамда аныкталган ар бир продукт үчүн ыкмаларды түзүү менен абстракттуу фабрика түзүңүз. Биздин учурда бул ыкмалар:
    • ProductA createProductA();
    • ProductB createProductB();
  5. Ар бир ишке ашыруу бир үй-бүлөнүн продукциясын түзүүнү көзөмөлдөш үчүн абстракттуу фабриканын реализацияларын түзүңүз. Бул үчүн, абстракттуу фабриканын ар бир ишке ашыруунун ичинде, бардык түзүү ыкмаларын ишке ашыруу зарыл, ошентип, продукциянын конкреттүү ишке ашырылышы алардын ичинде түзүлүп, кайра кайтарылат.
Төмөндө жогоруда сүрөттөлгөн көрсөтмөлөрдү чагылдырган UML диаграммасы келтирилген: Дизайн үлгүлөрү: AbstractFactory - 3Эми бул нускама үчүн codeду жазалы:
// Определим общие интерфейсы продуктов
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();
    }
}

Үй тапшырма

Материалды консолидациялоо үчүн сиз 2 нерсени жасай аласыз:
  1. Кофеге буйрутма берүү тиркемесин Linux'та иштеши үчүн жакшыртыңыз.
  2. Ар кандай стратегиянын бирдиктерин өндүрүү үчүн өзүңүздүн абстрактуу фабрикаңызды түзүңүз. Бул чыныгы армиялар менен тарыхый стратегия же орктар, эргежээлдер жана эльфтер менен болгон фантазия болушу мүмкүн. Эң негизгиси, бул сизге кызыктуу. Чыгармачылыкка ээ болуңуз, консолго пиндерди жайгаштырыңыз жана үлгүлөрдү үйрөнүңүз!
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION