Patterns: Abstract factory (Абстрактна фабрика) 1


Продовжую тему патернів проектування та алкоголю і хочу сьогодні розказати про патерн, який називається “абстрактна фабрика” (або ж “фабрика фабрик”). Розкажу на прикладі баби Параски, а все тому, що її “продукція” якраз і позиціонується як продукція якогось абстрактного спиртзаводу: баба Параска божиться, що купує на фабриці спирт і просто розводить водою, але яка фабрика виробляє таку гидоту конкретно сказати не може.

Насправді у патерні “абстрактна фабрика” все дуже просто, хоча це може здатися не так, якщо подивитися на оцю діаграму класів натверезо:

Абстрактна фабрика

Абстрактна фабрика

 

Але давайте подивимося як працює баба Параска, до якої вже якраз підійшов постійний клієнт.

Асортимент алкоголю, який можна придбати у Параски досить великий: вона пропонує кілька різних марок горілки (тут і недорогий “Княгинин” і “Хортиця” і навіть “Nemiroff”) та ще й коньяки (“Десна”, “Бучач”, “Дністер”, добре що нема “Хеннесі”). Хоча всі чудово розуміють, що розливається вся ця шняга з одної бочки а коньяк від горілки відрізняється лише тим, що у нього вмочили пакетик чаю, відбою від клієнтів у баби параски нема, тож сама вона вже не справляється. На щастя якраз на літо в гості завітали внучата Марічка та Іванко – чим не нагода навчити дітей заробляти копійчину?

Отже Параска тепер ночами розливає “продукцію” і ліпить пальоні акцизки, а вдень відпочиває на касі, де лиш бере у клієнта гроші, а омріяну пляшку йому приносять внуки. Причому має місце поділ праці: Івасик подає горілку, а Марічка – коньяк. Зараз картина трохи прояснилася:

Підпільна Алкоточка

Підпільна Алкоточка

Отже, що ми тут бачимо? Баба параска тут виступає у ролі інтерфейсу, тобто сама вона нічого не робить, а лиш кричить “дай пляшку!” котромусь зі своїх внучат. Відповідно кожен внук уже подає пляшку того, з дозволу сказати, напою, за який відповідає:

import асортимент.Бухло;
public interface БабаПараска {
    public Бухло дайПляшку();
}

import асортимент.Бухло;
import асортимент.ГорілкаКнягинин;
public class Івасик implements БабаПараска {
    public Бухло дайПляшку() {
        return new ГорілкаКнягинин();
    }
}

import асортимент.Бухло;
import асортимент.КоньякДністер;
public class Марічка implements БабаПараска {
    public Бухло дайПляшку() {
        return new КоньякДністер();
    }
}

Для зручності я зліпив вміст всіх трьох файлів докупи. Така сама картина і з алкоголем: все, що продається у цьому магазині – то звичайнісіньке низькопробне бухло (інтерфейс), просто замасковане під різні сорти горілки та коньяку:

package асортимент;
public interface Бухло {
    public void наливай();
}

package асортимент;
public class КоньякДністер implements Бухло{
    public void наливай() {
        System.out.println("Набираємо у пляшку мутну рідину з бочки, в якій плаває пакетик чаю");
    }
}

package асортимент;
public class ГорілкаКнягинин implements Бухло{
    public void наливай() {
        System.out.println("Набираємо у пляшку рідину з каністри розведеного спитряка у кутку");
    }
}

Тобто також маємо абстракцію, але ж контингент тут такий, що йому байдкже що пити, аби лиш “гребло”. Ось, до речі, і він: це наш старий знайомий синглтон дядько Вова з самісінького ранку припхався:

import асортимент.Бухло;
public class ПостійнийКлієнт {
    public ПостійнийКлієнт(БабаПараска хазяйка) {
        Бухло пляшка = хазяйка.дайПляшку();
        пляшка.наливай();
    }
}

Він окидає поглядом асортимент магазину і, силуючись згадати як же звати продавщицю, белькоче “хазяйка, дай пляшку” (вочевидь плануючи випити її просто тут). А далі спрацьовує уже добре відлагоджена схема абстрактної фабрики:

import асортимент.Бухло;
public class Main {
    public static void main(String[] args) {
        new ПостійнийКлієнт(хочуВипити("горілки"));
    }

    public static БабаПараска хочуВипити(String type) {
        if ("горілки".equals(type))
            return new Івасик();
        else
            return new Марічка();
    }
}

Дядько Володя вирішив що хоче горілки, про що і повідомляє метод хочуВипити(), передавши йому відповідний параметр. На підставі цього абстрактна фабрика вирішує кого із внуків відправити у підсобку. Цього разу піде Івасик, у реалізації якого сказано що треба набрати у пляшку смердючого спиртяку із каністри в кутку.

Отака повчальна історія, малята. Наостанок знову про те, де ж використовується згаданий патерн у самій Java, а це, як не дивно кидається у очі навіть з самої назви класів:

 

Гарного всім дня і пам’ятайте: бухати не варто, краще вивчайте Java 🙂

Почитайте ще оце:


Залиште коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Думка на тему “Patterns: Abstract factory (Абстрактна фабрика)