Sync Factory Method, Abstract Factory, Builder, Prototype to Java 25; fix post/code mismatches
This commit is contained in:
@@ -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"; }
|
||||
}
|
||||
|
||||
8
01-creational/factory-method/EmailSender.java
Normal file
8
01-creational/factory-method/EmailSender.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package factorymethod;
|
||||
|
||||
public class EmailSender extends NotificationSender {
|
||||
@Override
|
||||
protected Notification createNotification() {
|
||||
return new EmailNotification();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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%");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
31
01-creational/factory-method/NotificationSender.java
Normal file
31
01-creational/factory-method/NotificationSender.java
Normal 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");
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"; }
|
||||
}
|
||||
|
||||
8
01-creational/factory-method/PushSender.java
Normal file
8
01-creational/factory-method/PushSender.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package factorymethod;
|
||||
|
||||
public class PushSender extends NotificationSender {
|
||||
@Override
|
||||
protected Notification createNotification() {
|
||||
return new PushNotification();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/SlackNotification.java
Normal file
11
01-creational/factory-method/SlackNotification.java
Normal 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"; }
|
||||
}
|
||||
9
01-creational/factory-method/SlackSender.java
Normal file
9
01-creational/factory-method/SlackSender.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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"; }
|
||||
}
|
||||
|
||||
8
01-creational/factory-method/SmsSender.java
Normal file
8
01-creational/factory-method/SmsSender.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package factorymethod;
|
||||
|
||||
public class SmsSender extends NotificationSender {
|
||||
@Override
|
||||
protected Notification createNotification() {
|
||||
return new SmsNotification();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user