javaintermediate

Factory Method Pattern with Registry

Implement the Factory pattern using a registry map for extensible object creation without switch statements.

java
import java.util.*;
import java.util.function.Supplier;

// Product interface
interface Notification {
    void send(String to, String message);
}

// Concrete products
class EmailNotification implements Notification {
    public void send(String to, String message) {
        System.out.printf("EMAIL to %s: %s%n", to, message);
    }
}

class SmsNotification implements Notification {
    public void send(String to, String message) {
        System.out.printf("SMS to %s: %s%n", to, message);
    }
}

class SlackNotification implements Notification {
    public void send(String to, String message) {
        System.out.printf("SLACK to #%s: %s%n", to, message);
    }
}

// Factory with registry
class NotificationFactory {
    private static final Map<String, Supplier<Notification>> registry = new HashMap<>();

    static {
        registry.put("email", EmailNotification::new);
        registry.put("sms", SmsNotification::new);
        registry.put("slack", SlackNotification::new);
    }

    // Register new types at runtime
    public static void register(String type, Supplier<Notification> creator) {
        registry.put(type.toLowerCase(), creator);
    }

    public static Notification create(String type) {
        Supplier<Notification> creator = registry.get(type.toLowerCase());
        if (creator == null) {
            throw new IllegalArgumentException("Unknown notification type: " + type);
        }
        return creator.get();
    }

    public static Set<String> availableTypes() {
        return Collections.unmodifiableSet(registry.keySet());
    }
}

public class FactoryDemo {
    public static void main(String[] args) {
        Notification n = NotificationFactory.create("email");
        n.send("alice@test.com", "Hello from factory!");

        // Register custom type
        NotificationFactory.register("webhook", () -> (to, msg) ->
            System.out.printf("WEBHOOK %s: %s%n", to, msg));

        NotificationFactory.create("webhook").send("url", "Custom!");
        System.out.println("Types: " + NotificationFactory.availableTypes());
    }
}

Use Cases

  • Extensible object creation in plugin architectures
  • Decoupling client code from concrete implementations
  • Service provider pattern for notifications or parsers

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.