Kihagyás

Simple / Static Factory Method

Lényege és célja

A Simple Factory (vagy Statikus Factory Metódus) szigorúan véve nem tartozik a klasszikus GoF (Gang of Four) tervezési minták közé, inkább egy nagyon elterjedt programozási idióma.

A lényege, hogy az objektumok létrehozását (a new kulcsszó használatát) egy különálló osztály statikus metódusába (vagy magába az osztályba) rejtjük el. A kliens kód nem hívja meg közvetlenül a konstruktort, hanem a Factory metódustól "kéri el" a kész példányt.

Miért jobb, mint egy sima konstruktor?

  1. Beszédes nevek: Egy konstruktor neve mindig megegyezik az osztály nevével. Egy statikus metódusnak viszont adhatunk beszédes nevet (pl. valueOf(), getInstance(), createFromXml()).
  2. Polimorfizmus: A metódus visszatérési típusa lehet egy interfész vagy ősosztály, így futásidőben eldöntheti, hogy pontosan melyik alosztály példányát adja vissza.
  3. Példányok újrahasznosítása (Caching): A konstruktor mindig garantáltan egy új objektumot hoz létre a memóriában. Egy statikus metódus viszont visszaadhat egy már létező, lecache-elt példányt is (pl. Integer.valueOf(5)).

Mikor használjuk?

  • Amikor az objektum létrehozásának logikája (pl. egy switch-case vagy if-else ág a típus kiválasztására) túl bonyolult ahhoz, hogy a kliens kódban szétszórva szerepeljen.
  • Amikor szeretnénk a kliens kódot leválasztani a konkrét implementációs osztályokról (laza csatolás), és csak az interfészen keresztül kommunikálni.

Mermaid Diagram

Az alábbi ábrán látható, ahogy a kliens csak a Factory-val és a közös Notification interfésszel áll kapcsolatban, a konkrét osztályokat (EmailNotification, SmsNotification) a Factory hozza létre a háttérben.

classDiagram
    class Client

    class NotificationFactory {
        <<utility>>
        +createNotification(type: String)$ Notification
    }

    class Notification {
        <<interface>>
        +send() void
    }

    class EmailNotification {
        +send() void
    }

    class SmsNotification {
        +send() void
    }

    Client --> NotificationFactory : "használja"
    Client --> Notification : "ismeri"

    NotificationFactory ..> EmailNotification : "példányosítja"
    NotificationFactory ..> SmsNotification : "példányosítja"

    EmailNotification ..|> Notification : "implementálja"
    SmsNotification ..|> Notification : "implementálja"

Forráskód

package creational.simple_factory_method;

interface Notification {
    void send();
}

class EmailNotification implements Notification {
    @Override
    public void send() {
        System.out.println("Sending Email...");
    }
}

class SmsNotification implements Notification {
    @Override
    public void send() {
        System.out.println("Sending SMS...");
    }
}

class NotificationFactory {

    static Notification createNotification(String type) {
        return switch (type) {
            case "email" -> new EmailNotification();
            case "sms" -> new SmsNotification();
            case null, default -> throw new IllegalArgumentException();
        };
    }
}

class Main {
    static void main() {

        // simple factory
        NotificationFactory.createNotification("sms").send();
    }
}