Wzorzec Projektowy Fabryka

Wzorzec projektowania fabryka jest jednym z najpopularniejszych wzorców projektowania.
W skrócie polega on na zdefiniowaniu interfejsu, który umożliwia tworzenie obiektów, a następnie na utworzeniu jednej lub kilku klas, które implementują ten interfejs i służą do tworzenia różnych typów obiektów.

Wzorzec ten znacznie ułatwia proces tworzenia obiektów, ponieważ pozwala na skupienie się na tworzeniu ich instancji zamiast na samych krokach tworzenia. To pozwala na bardziej elastyczny i efektywny sposób projektowania oprogramowania.

Zasada działania wzorca Fabryka

Podstawową ideą wzorca fabryka jest zdefiniowanie klasy, która ma na celu tworzenie obiektów innych klas. Ta klasa nazywana jest fabryką, ponieważ jest odpowiedzialna za produkcję obiektów. Aby zrealizować ten wzorzec projektowania, potrzebujemy trzech podstawowych elementów:

Podstawowe elementy wzorca Fabryka

Interfejs – to abstrakcyjna klasa lub interfejs, który definiuje metody, jakie musi zaimplementować klasa fabrykująca. Interfejs określa również typ obiektów, które ma zwracać fabryka.

Klasa fabrykująca – to klasa, która implementuje interfejs i zawiera logikę tworzenia obiektów. Wzorzec ten może mieć wiele różnych klas fabrykujących, które mogą tworzyć różne rodzaje obiektów.

Klasa konkretna – to klasa, która implementuje interfejs i zawiera logikę tworzenia obiektu. Każda klasa konkretna jest tworzona przez klasę fabrykującą i musi zaimplementować metody interfejsu.

Wzorzec Fabryka można zaimplementować na różne sposoby. Jednym z najprostszych jest stworzenie jednej klasy fabrykującej, która ma metody tworzące konkretne obiekty. W ten sposób, gdy chcemy dodać nowy typ obiektu, musimy jedynie zmienić kod klasy fabrykującej.

Przykład implementacji we wzorcu Fabryka

// 1. Tworzymy interfejs Product, który będzie implementować klasy konkretne
interface Product {
    void printDescription();
}

// 2. Tworzymy klasy implementujące interfejs Product
class ProductA implements Product {
    @Override
    public void printDescription() {
        System.out.println("Jestem produktem typu A");
    }
}

class ProductB implements Product {
    @Override
    public void printDescription() {
        System.out.println("Jestem produktem typu B");
    }
}

// 3. Tworzymy klasę Fabryka, która będzie odpowiedzialna za tworzenie obiektów
class Factory {
// 4. Metoda createProduct() tworzy nowy obiekt Product, zwracając go jako interfejs
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ProductA();
        } else if (type.equals("B")) {
            return new ProductB();
        } else {
            throw new IllegalArgumentException("Nieznany typ produktu");
        }
    }
}

// 5. Wykonanie programu we wzorcu Fabryka
public class Main {
    public static void main(String[] args) {
        Product productA = Factory.createProduct("A");
        productA.printDescription(); // Wypisze: "Jestem produktem typu A"
        
        Product productB = Factory.createProduct("B");
        productB.printDescription(); // Wypisze: "Jestem produktem typu B"
    }
}