Menu
Coddy logo textTech

Wzorzec Factory

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 66 z 87.

Wzorzec fabryki to kreacyjny wzorzec projektowy, który przekazuje tworzenie obiektów osobnej metodzie lub klasie. Zamiast używać bezpośrednio new w swoim kodzie, prosisz fabrykę o utworzenie obiektów. Jest to szczególnie przydatne, gdy masz wiele powiązanych klas współdzielących wspólny interfejs lub klasę nadrzędną.

Rozważ system powiadomień, który może wysyłać e-maile, SMS-y lub powiadomienia push. Bez fabryki kod musiałby znać każdą konkretną klasę:

// Bez fabryki — kod klienta musi znać wszystkie klasy konkretne
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

Wzorzec Fabryka pozwala scentralizować tę logikę tworzenia:

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

Teraz kod klienta jest czytelniejszy i nie zależy od konkretnych klas:

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Wynik: Email: Hello!

Główną zaletą jest to, że dodanie nowych typów powiadomień wymaga aktualizacji tylko fabryki: kod klienta pozostaje bez zmian. Jest to zgodne z zasadą programowania do interfejsu, dzięki czemu system jest bardziej elastyczny i łatwiejszy do rozszerzania.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system rysowania kształtów, używając wzorca Factory! Zamiast tworzyć obiekty kształtów bezpośrednio w różnych miejscach kodu, scentralizujesz logikę ich tworzenia w fabryce, która tworzy różne typy kształtów na podstawie prostego identyfikatora tekstowego.

Rozmieścisz kod w czterech plikach:

  • Shape.java: Zdefiniuj interfejs o nazwie Shape, który będzie wspólnym kontraktem dla wszystkich kształtów. Twój interfejs powinien deklarować jedną metodę draw(), która nic nie zwraca, ale wyświetla informacje o rysowanym kształcie.
  • Shapes.java: Utwórz trzy klasy implementujące interfejs Shape:

    Circle — jego metoda draw() powinna wyświetlać Drawing a Circle

    Rectangle — jego metoda draw() powinna wyświetlać Drawing a Rectangle

    Triangle — jego metoda draw() powinna wyświetlać Drawing a Triangle

  • ShapeFactory.java: Utwórz klasę fabryki, która obsługuje tworzenie kształtów. Klasa ShapeFactory powinna mieć metodę statyczną createShape(String type), która zwraca obiekt typu Shape. W zależności od parametru type:
    • Jeśli type jest równe "circle", zwróć nowy obiekt klasy Circle
    • Jeśli type jest równe "rectangle", zwróć nowy obiekt klasy Rectangle
    • Jeśli type jest równe "triangle", zwróć nowy obiekt klasy Triangle
    • Dla każdej innej wartości zwróć null
  • Main.java: Połącz wszystkie elementy systemu fabryki! Otrzymasz dwa wejścia: dwa typy kształtów (oba typu String).

    Dla każdego wejścia użyj klasy ShapeFactory, aby utworzyć kształt i zapisać go w zmiennej typu Shape. Jeśli fabryka zwróci prawidłowy kształt (inny niż null), wywołaj jego metodę draw(). Jeśli zwróci null, wyświetl Unknown shape: [type], gdzie [type] to przekazane wejście.

    Przetwórz oba wejścia po kolei, wyświetlając wynik każdego z nich w osobnym wierszu.

Otrzymasz po kolei dwa wejścia: typ pierwszego kształtu (String) i typ drugiego kształtu (String).

Zwróć uwagę, że Twoja klasa Main nigdy nie używa bezpośrednio new Circle() ani new Rectangle(). Zna jedynie interfejs Shape i prosi fabrykę o utworzenie obiektów. Na tym polega siła wzorca Factory: kod klienta jest niezależny od konkretnych klas!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dwa typy figur
        String type1 = scanner.nextLine();
        String type2 = scanner.nextLine();
        
        // TODO: Użyj ShapeFactory, aby utworzyć pierwszą figurę
        // Jeśli figura nie jest null, wywołaj draw()
        // Jeśli figura jest null, wypisz "Unknown shape: [type]"
        
        // TODO: Zrób to samo dla drugiej figury
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online