Kihagyás

Factory Method (Gyártófüggvény)

Kategória: Létrehozási minta (Creational Pattern)

Lényege és célja

A Factory Method egy klasszikus tervezési minta, amely egy interfészt (vagy absztrakt osztályt) biztosít az objektumok létrehozásához, de az alosztályokra bízza a döntést, hogy pontosan melyik osztályt példányosítsák. Más szóval: az objektum létrehozásának felelősségét "letolja" az alosztályok szintjére.

A kliens kód (amelyik használni akarja a terméket) egyáltalán nem ismeri a konkrét osztályokat, csak a Factory és a Product interfészekkel kommunikál.

Miben más, mint a Simple Factory?

Amíg a Simple Factory egyetlen osztályban, gyakran egy nagy switch-case vagy if-else blokkban dönti el, mit hozzon létre, addig a Factory Method a polimorfizmust hívja segítségül. Itt maga a Factory is egy interfész. Ha be akarunk vezetni egy új típust (pl. PushNotification), nem kell meglévő kódot módosítanunk (nincs switch-case bővítés), csak létrehozunk egy új terméket és egy új, hozzá tartozó gyárat. Ez a minta a tökéletes megtestesítője az Open/Closed Principle-nek (Nyitott a bővítésre, zárt a módosításra).

Mikor használjuk?

  • Amikor előre nem tudjuk, hogy pontosan milyen típusú objektumokkal kell majd dolgoznia a kódunknak.
  • Amikor a rendszerünket úgy akarjuk felépíteni, hogy az később könnyen bővíthető legyen új típusokkal, a meglévő (és már letesztelt) kód kockáztatása nélkül.
  • Amikor egy könyvtárat vagy keretrendszert írunk, és lehetőséget akarunk adni a felhasználóknak, hogy a saját belső komponenseinket kiterjesszék.

Mermaid Diagram

Az alábbi ábrán jól látszik, hogy két párhuzamos hierarchia fut: a Termékeké (Notification) és a Gyáraké (NotificationFactory). A kliensnek (Main) csak a legfelső interfészeket kell ismernie.

classDiagram
    %% Termékek hierarchiája
    class Notification {
        <<interface>>
        +send() void
    }
    class EmailNotification {
        +send() void
    }
    class SmsNotification {
        +send() void
    }
    EmailNotification ..|> Notification : "implementálja"
    SmsNotification ..|> Notification : "implementálja"

    %% Gyárak hierarchiája
    class NotificationFactory {
        <<interface>>
        +createNotification() Notification
    }
    class EmailNotificationFactory {
        +createNotification() Notification
    }
    class SmsNotificationFactory {
        +createNotification() Notification
    }
    EmailNotificationFactory ..|> NotificationFactory : "implementálja"
    SmsNotificationFactory ..|> NotificationFactory : "implementálja"

    %% Kapcsolat a gyárak és a termékek között
    EmailNotificationFactory ..> EmailNotification : "példányosítja"
    SmsNotificationFactory ..> SmsNotification : "példányosítja"

    %% Kliens használat
    class Client
    Client --> NotificationFactory : "használja"
    Client --> Notification : "kapja"

Forráskód

package creational.factory_method;

interface Notification {
    void send();
}

interface NotificationFactory {
    Notification createNotification();
}

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

class EmailNotificationFactory implements NotificationFactory {
    @Override
    public Notification createNotification() {
        return new EmailNotification();
    }
}

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

class SmsNotificationFactory implements NotificationFactory {
    @Override
    public Notification createNotification() {
        return new SmsNotification();
    }
}


class Main {
    static void main() {
        NotificationFactory notificationFactory = new SmsNotificationFactory();
        notificationFactory.createNotification().send();
    }
}