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?
- 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()). - 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.
- 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-casevagyif-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();
}
}