Sync Factory Method, Abstract Factory, Builder, Prototype to Java 25; fix post/code mismatches

This commit is contained in:
2026-06-23 11:00:02 +05:30
parent 2f684bf3d7
commit 2fbf89875b
51 changed files with 634 additions and 337 deletions

View File

@@ -1,11 +1,13 @@
package factorymethod;
public class EmailNotification implements Notification {
private final String email;
public EmailNotification(String email) { this.email = email; }
@Override
public void send(String message) {
System.out.println("Email -> " + email + ": " + message);
public void send(String recipient, String message) {
// In production: use JavaMail or Spring Mail
System.out.printf(" [EMAIL] To: %s | Body: %s%n", recipient, message);
}
@Override
public String getType() { return "EMAIL"; }
}

View File

@@ -0,0 +1,8 @@
package factorymethod;
public class EmailSender extends NotificationSender {
@Override
protected Notification createNotification() {
return new EmailNotification();
}
}

View File

@@ -1,11 +0,0 @@
package factorymethod;
public class EmailService extends NotificationService {
private final String email;
public EmailService(String email) { this.email = email; }
@Override
protected Notification createNotification() {
return new EmailNotification(email);
}
}

View File

@@ -1,17 +1,23 @@
package factorymethod;
public class Main {
public static void main(String[] args) {
System.out.println("=== Factory Method Pattern Demo ===\n");
NotificationService[] services = {
new EmailService("alice@example.com"),
new SmsService("+1-555-0123"),
new PushService("device-token-abc123")
};
// The client only knows about NotificationSender (the Creator)
NotificationSender sender;
for (NotificationService service : services) {
service.notifyUser("Your order #1042 has been shipped!");
}
sender = new EmailSender();
sender.notify("alice@example.com", "Your order has shipped!");
sender = new SmsSender();
sender.notify("+1-555-0100", "OTP: 482910");
sender = new PushSender();
sender.notify("device-token-xyz", "New message from Bob");
// Adding Slack: just swap the creator. Client code doesn't change.
sender = new SlackSender(); // new class, nothing else touched
sender.notify("#alerts", "CPU usage above 90%");
}
}

View File

@@ -1,5 +1,11 @@
package factorymethod;
public interface Notification {
void send(String message);
// Every notification must know how to deliver itself
void send(String recipient, String message);
// Used by the Creator for logging — it needs to know the type
// without knowing the concrete class
String getType();
}

View File

@@ -0,0 +1,31 @@
package factorymethod;
public abstract class NotificationSender {
// THE factory method — this is the one thing subclasses override.
// It returns a Notification (the Product interface), never a concrete class.
protected abstract Notification createNotification();
// The shared workflow — marked final so subclasses cannot change it.
// It calls createNotification() to get the right notification,
// then runs the same steps every time regardless of which channel was created.
public final void notify(String recipient, String message) {
Notification notification = createNotification(); // delegate creation
System.out.println("Sending " + notification.getType() + " notification...");
notification.send(recipient, message); // use the Product interface
System.out.println("Delivered.");
}
// Shared retry logic — works for all channels without change
public void notifyWithRetry(String recipient, String message, int maxRetries) {
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
notify(recipient, message);
return; // success — exit
} catch (Exception e) {
System.err.printf("Attempt %d failed: %s%n", attempt, e.getMessage());
}
}
throw new RuntimeException("All " + maxRetries + " attempts failed");
}
}

View File

@@ -1,11 +1,24 @@
package factorymethod;
/** Creator - declares the factory method */
public abstract class NotificationService {
protected abstract Notification createNotification();
public class NotificationService {
public void notifyUser(String message) {
Notification n = createNotification();
n.send(message);
public void send(String type, String recipient, String message) {
// Creation logic mixed with business logic
Notification notification;
if ("EMAIL".equals(type)) {
notification = new EmailNotification();
} else if ("SMS".equals(type)) {
notification = new SmsNotification();
} else if ("PUSH".equals(type)) {
notification = new PushNotification();
} else {
throw new IllegalArgumentException("Unknown type: " + type);
}
// Business logic that should never change
System.out.println("Sending " + type + " to " + recipient);
notification.send(recipient, message);
System.out.println("Delivered.");
}
}

View File

@@ -1,11 +1,13 @@
package factorymethod;
public class PushNotification implements Notification {
private final String deviceToken;
public PushNotification(String deviceToken) { this.deviceToken = deviceToken; }
@Override
public void send(String message) {
System.out.println("Push -> " + deviceToken + ": " + message);
public void send(String recipient, String message) {
// In production: use Firebase FCM
System.out.printf(" [PUSH] To: %s | Alert: %s%n", recipient, message);
}
@Override
public String getType() { return "PUSH"; }
}

View File

@@ -0,0 +1,8 @@
package factorymethod;
public class PushSender extends NotificationSender {
@Override
protected Notification createNotification() {
return new PushNotification();
}
}

View File

@@ -1,11 +0,0 @@
package factorymethod;
public class PushService extends NotificationService {
private final String token;
public PushService(String token) { this.token = token; }
@Override
protected Notification createNotification() {
return new PushNotification(token);
}
}

View File

@@ -0,0 +1,11 @@
package factorymethod;
// New Concrete Product — knows how to send to Slack
public class SlackNotification implements Notification {
@Override
public void send(String recipient, String message) {
System.out.printf(" [SLACK] Channel: %s | Message: %s%n", recipient, message);
}
@Override
public String getType() { return "SLACK"; }
}

View File

@@ -0,0 +1,9 @@
package factorymethod;
// New Concrete Creator — knows to create a SlackNotification
public class SlackSender extends NotificationSender {
@Override
protected Notification createNotification() {
return new SlackNotification();
}
}

View File

@@ -1,11 +1,13 @@
package factorymethod;
public class SmsNotification implements Notification {
private final String phone;
public SmsNotification(String phone) { this.phone = phone; }
@Override
public void send(String message) {
System.out.println("SMS -> " + phone + ": " + message);
public void send(String recipient, String message) {
// In production: use Twilio SDK
System.out.printf(" [SMS] To: %s | Text: %s%n", recipient, message);
}
@Override
public String getType() { return "SMS"; }
}

View File

@@ -0,0 +1,8 @@
package factorymethod;
public class SmsSender extends NotificationSender {
@Override
protected Notification createNotification() {
return new SmsNotification();
}
}

View File

@@ -1,11 +0,0 @@
package factorymethod;
public class SmsService extends NotificationService {
private final String phone;
public SmsService(String phone) { this.phone = phone; }
@Override
protected Notification createNotification() {
return new SmsNotification(phone);
}
}