CodeGym/Blog Java/Random-PL/Fabryczny wzór projektowy
Autor
Andrey Gorkovenko
Frontend Engineer at NFON AG

Fabryczny wzór projektowy

Opublikowano w grupie Random-PL
Cześć przyjacielu! Dzisiaj będziemy kontynuować badanie wzorców projektowych. W tej lekcji porozmawiamy o fabrykach. Omówimy problem, który rozwiązuje ten wzorzec i przyjrzymy się przykładowi, jak fabryka może pomóc w otwarciu kawiarni. Dodatkowo podam 5 prostych kroków do stworzenia fabryki. Fabryczny wzór projektowy - 1 Aby upewnić się, że wszyscy nadajemy na tych samych falach i że szybko zrozumiesz tę koncepcję, powinieneś zapoznać się z następującymi tematami:
  • Dziedziczenie w Javie
  • Zawężanie i rozszerzanie typów referencyjnych w Javie
  • Interakcja między różnymi klasami i obiektami.

Co to jest fabryka?

Wzorzec projektowania fabryki pozwala kontrolować tworzenie obiektów. Proces tworzenia nowego obiektu nie jest super prosty, ale nie jest też przesadnie skomplikowany. Wszyscy wiemy, że potrzebujemy newoperatora do stworzenia nowego obiektu. Być może wydaje się, że nie ma tu nic do kontrolowania, ale to nieprawda. Załóżmy, że nasza aplikacja ma pewną klasę, która ma wielu potomków. Trudności mogą pojawić się, gdy konieczne jest utworzenie instancji określonej klasy w zależności od określonych warunków. Fabryka to wzorzec projektowy, który pomaga rozwiązać problem tworzenia różnych obiektów w zależności od określonych warunków . Jak to się ma do abstrakcyjnego pojęcia? Stanie się to jaśniejsze i bardziej szczegółowe, gdy spojrzymy na poniższy przykład.

Przygotujmy różne rodzaje kawy

Załóżmy, że chcemy zautomatyzować kawiarnię. Musimy nauczyć nasz program, jak robić różne rodzaje kawy. W tym celu utworzymy klasę kawy i kilka klas pochodnych reprezentujących rodzaje kawy, które będziemy przygotowywać: Americano, cappuccino, espresso i latte. Zacznijmy od ogólnej klasy kawy:
public class Coffee {
    public void grindCoffee(){
        // Grind the coffee
    }
    public void makeCoffee(){
        // Brew the coffee
    }
    public void pourIntoCup(){
        // Pour into a cup
    }
}
Następnie utworzymy jego klasy potomne:
public class Americano extends Coffee {}
public class Cappuccino extends Coffee {}
public class CaffeLatte extends Coffee {}
public class Espresso extends Coffee {}
Nasi klienci mogą zamówić każdy rodzaj kawy. Ich rozkazy muszą zostać przekazane do programu. Można to zrobić na wiele sposobów, na przykład za pomocą String. Ale enumnajlepszy jest do tego. Stworzymy enumi zdefiniujemy pola wyliczeniowe odpowiadające rodzajom kawy, które można zamówić:
public enum CoffeeType {
    ESPRESSO,
    AMERICANO,
    CAFFE_LATTE,
    CAPPUCCINO
}
Świetnie. Teraz napiszmy kod dla naszej kawiarni:
public class CoffeeShop {

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucсino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
Metodę orderCoffeemożna podzielić na dwie części:
  1. Stworzenie konkretnego egzemplarza kawy w switchzestawieniu. W tym miejscu fabryka robi to, co robi — tworzy określony typ w zależności od warunków.
  2. Przygotowanie — to mielenie, zaparzanie i nalewanie do filiżanki.
Oto, co należy wiedzieć, jeśli w przyszłości trzeba będzie wprowadzić zmiany w metodzie:
  1. Czynności związane z samym przygotowaniem (mielenie, zaparzanie i nalewanie do filiżanki) pozostaną niezmienione (przynajmniej na to liczymy).
  2. Ale asortyment kaw może ulec zmianie. Może zaczniemy robić mokkę... Frappu... Mochacci... Nieważne, nowy rodzaj kawy.
Już teraz możemy być pewni, że w przyszłości będziemy musieli wprowadzić zmiany w switchinstrukcji metody. Niewykluczone również, że w naszej kawiarni orderCoffeemetoda nie będzie jedynym miejscem, w którym będziemy tworzyć różne rodzaje kaw. W rezultacie zmiany będą musiały zostać wprowadzone w kilku miejscach. Pewnie już rozumiesz, o co mi chodzi. Musimy dokonać refaktoryzacji. Przenieś blok odpowiedzialny za tworzenie kawy do osobnej klasy z dwóch powodów:
  1. Możemy ponownie wykorzystać logikę parzenia kawy w innych miejscach.
  2. Jeśli zmieni się asortyment, nie będziemy musieli edytować kodu wszędzie tam, gdzie powstaje kawa. Wystarczy zmienić nasz kod w jednym miejscu.
Innymi słowy, nadszedł czas na założenie fabryki.

Założenie naszej pierwszej fabryki

W tym celu utworzymy nową klasę, która będzie odpowiedzialna tylko za tworzenie niezbędnych wystąpień klas kawy:
public class SimpleCoffeeFactory {
    public Coffee createCoffee(CoffeeType type) {
        Coffee coffee = null;

        switch (type) {
            case AMERICANO:
                coffee = new Americano();
                break;
            case ESPRESSO:
                coffee = new Espresso();
                break;
            case CAPPUCCINO:
                coffee = new Cappucino();
                break;
            case CAFFE_LATTE:
                coffee = new CaffeLatte();
                break;
        }

        return coffee;
    }
}
Gratulacje! Właśnie zaimplementowaliśmy wzorzec projektowania fabryki w jego najprostszej (prawie) formie. Mogłoby być jeszcze prościej, gdybyśmy uczynili createCoffeemetodę statyczną. Ale wtedy stracilibyśmy dwie możliwości:
  1. Możliwość dziedziczenia SimpleCoffeeFactoryi zastępowania createCoffeemetody.
  2. Możliwość dodania wymaganej implementacji fabrycznej do naszych klas.
A propos wdrożenia... Musimy wrócić do kawiarni i dodać naszą fabrykę do parzenia kawy.

Dodanie fabryki do kawiarni

Przepiszmy klasę kawiarni, używając fabryki:
public class CoffeeShop {

    private final SimpleCoffeeFactory coffeeFactory;

    public CoffeeShop(SimpleCoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(CoffeeType type) {
        Coffee coffee = coffeeFactory.createCoffee(type);
        coffee.grindCoffee();
        coffee.makeCoffee();
        coffee.pourIntoCup();

        System.out.println("Here's your coffee! Thanks! Come again!");
        return coffee;
    }
}
Doskonały. Teraz przedstawimy zwięzły opis ogólnej struktury wzorca projektowego fabryki.

5 kroków do otwarcia własnej fabryki

Krok 1. Twój program ma klasę z kilkoma potomkami, jak na poniższym diagramie: Fabryczny wzór projektowy - 2Krok 2. Tworzysz pole enumz polem dla każdej klasy potomnej:
enum CatType {
    LION,
    TIGER,
    FLUFFY
}
Krok 3. Zbuduj swoją fabrykę. Nazwij to CatFactory. Oto kod:
class CatFactory {}
Krok 4. Utwórz w swojej fabryce createCatmetodę, która pobiera CatTypeargument. Oto kod:
class CatFactory {
    public Cat createCat(CatType type) {

    }
}
Krok 5. W ciele metody napisz switchinstrukcję, która wylicza pola enum i tworzy instancję klasy odpowiadającą przekazanej enumwartości:
class CatFactory {
        public Cat createCat(CatType type) {
            Cat cat = null;

            switch (type) {
                case LION:
                    cat =  new Fluffy();
                    break;
                case TIGER:
                    cat = new Tiger();
                    break;
                case FLUFFY:
                    cat =  new Lion();
                    break;
            }

            return cat;
        }
    }
Teraz możesz prowadzić fabrykę jak szef. :)

Jak ćwiczyć

Czytanie jest dobre, pisanie kodu jest jeszcze lepsze. Jeśli Twoje imię i nazwisko składa się z parzystej liczby liter, spróbuj stworzyć własną wirtualną pizzerię. Jeśli Twoje imię i nazwisko składa się z nieparzystej liczby liter, spróbuj utworzyć wirtualny bar sushi. Jeśli nie masz imienia, masz szczęście. Dziś możesz odpocząć.
Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy