Add creational patterns, Interpreter; remove scripts; update README
This commit is contained in:
21
01-creational/abstract-factory/Application.java
Normal file
21
01-creational/abstract-factory/Application.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package abstractfactory;
|
||||
|
||||
/** Client - uses the factory without knowing concrete classes */
|
||||
public class Application {
|
||||
private final Button button;
|
||||
private final Checkbox checkbox;
|
||||
|
||||
public Application(GUIFactory factory) {
|
||||
button = factory.createButton();
|
||||
checkbox = factory.createCheckbox();
|
||||
}
|
||||
|
||||
public void render() {
|
||||
button.render();
|
||||
checkbox.render();
|
||||
}
|
||||
|
||||
public void simulateClick() {
|
||||
button.onClick();
|
||||
}
|
||||
}
|
||||
6
01-creational/abstract-factory/Button.java
Normal file
6
01-creational/abstract-factory/Button.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package abstractfactory;
|
||||
|
||||
public interface Button {
|
||||
void render();
|
||||
void onClick();
|
||||
}
|
||||
5
01-creational/abstract-factory/Checkbox.java
Normal file
5
01-creational/abstract-factory/Checkbox.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package abstractfactory;
|
||||
|
||||
public interface Checkbox {
|
||||
void render();
|
||||
}
|
||||
7
01-creational/abstract-factory/GUIFactory.java
Normal file
7
01-creational/abstract-factory/GUIFactory.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package abstractfactory;
|
||||
|
||||
/** Abstract Factory - creates families of related UI components */
|
||||
public interface GUIFactory {
|
||||
Button createButton();
|
||||
Checkbox createCheckbox();
|
||||
}
|
||||
6
01-creational/abstract-factory/MacButton.java
Normal file
6
01-creational/abstract-factory/MacButton.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class MacButton implements Button {
|
||||
@Override public void render() { System.out.println("[Mac] Rendering button with rounded corners"); }
|
||||
@Override public void onClick() { System.out.println("[Mac] Button clicked - glow animation"); }
|
||||
}
|
||||
5
01-creational/abstract-factory/MacCheckbox.java
Normal file
5
01-creational/abstract-factory/MacCheckbox.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class MacCheckbox implements Checkbox {
|
||||
@Override public void render() { System.out.println("[Mac] Rendering checkbox with rounded tick box"); }
|
||||
}
|
||||
6
01-creational/abstract-factory/MacFactory.java
Normal file
6
01-creational/abstract-factory/MacFactory.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class MacFactory implements GUIFactory {
|
||||
@Override public Button createButton() { return new MacButton(); }
|
||||
@Override public Checkbox createCheckbox() { return new MacCheckbox(); }
|
||||
}
|
||||
22
01-creational/abstract-factory/Main.java
Normal file
22
01-creational/abstract-factory/Main.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Abstract Factory Pattern Demo ===\n");
|
||||
|
||||
String os = System.getProperty("os.name", "Windows").toLowerCase();
|
||||
GUIFactory factory = os.contains("mac") ? new MacFactory() : new WindowsFactory();
|
||||
|
||||
System.out.println("Detected OS family: " + (os.contains("mac") ? "Mac" : "Windows"));
|
||||
System.out.println();
|
||||
|
||||
Application app = new Application(factory);
|
||||
app.render();
|
||||
app.simulateClick();
|
||||
|
||||
System.out.println("\n--- Forcing Mac UI ---");
|
||||
Application macApp = new Application(new MacFactory());
|
||||
macApp.render();
|
||||
macApp.simulateClick();
|
||||
}
|
||||
}
|
||||
6
01-creational/abstract-factory/WindowsButton.java
Normal file
6
01-creational/abstract-factory/WindowsButton.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class WindowsButton implements Button {
|
||||
@Override public void render() { System.out.println("[Windows] Rendering button with square corners"); }
|
||||
@Override public void onClick() { System.out.println("[Windows] Button clicked - raised border effect"); }
|
||||
}
|
||||
5
01-creational/abstract-factory/WindowsCheckbox.java
Normal file
5
01-creational/abstract-factory/WindowsCheckbox.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class WindowsCheckbox implements Checkbox {
|
||||
@Override public void render() { System.out.println("[Windows] Rendering checkbox with square tick box"); }
|
||||
}
|
||||
6
01-creational/abstract-factory/WindowsFactory.java
Normal file
6
01-creational/abstract-factory/WindowsFactory.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package abstractfactory;
|
||||
|
||||
public class WindowsFactory implements GUIFactory {
|
||||
@Override public Button createButton() { return new WindowsButton(); }
|
||||
@Override public Checkbox createCheckbox() { return new WindowsCheckbox(); }
|
||||
}
|
||||
12
01-creational/builder/Director.java
Normal file
12
01-creational/builder/Director.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package builder;
|
||||
|
||||
/** Director knows how to build common configurations */
|
||||
public class Director {
|
||||
public House buildStarter(House.Builder builder) {
|
||||
return builder.rooms(2).floors(1).garage(false).roofType("gabled").build();
|
||||
}
|
||||
|
||||
public House buildLuxury(House.Builder builder) {
|
||||
return builder.rooms(6).floors(3).garage(true).garden(true).pool(true).roofType("hip").build();
|
||||
}
|
||||
}
|
||||
43
01-creational/builder/House.java
Normal file
43
01-creational/builder/House.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package builder;
|
||||
|
||||
public class House {
|
||||
private final int rooms;
|
||||
private final int floors;
|
||||
private final boolean hasGarage;
|
||||
private final boolean hasGarden;
|
||||
private final boolean hasPool;
|
||||
private final String roofType;
|
||||
|
||||
private House(Builder builder) {
|
||||
this.rooms = builder.rooms;
|
||||
this.floors = builder.floors;
|
||||
this.hasGarage = builder.hasGarage;
|
||||
this.hasGarden = builder.hasGarden;
|
||||
this.hasPool = builder.hasPool;
|
||||
this.roofType = builder.roofType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "House{rooms=" + rooms + ", floors=" + floors
|
||||
+ ", garage=" + hasGarage + ", garden=" + hasGarden
|
||||
+ ", pool=" + hasPool + ", roof='" + roofType + "'}";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int rooms = 1;
|
||||
private int floors = 1;
|
||||
private boolean hasGarage = false;
|
||||
private boolean hasGarden = false;
|
||||
private boolean hasPool = false;
|
||||
private String roofType = "flat";
|
||||
|
||||
public Builder rooms(int rooms) { this.rooms = rooms; return this; }
|
||||
public Builder floors(int floors) { this.floors = floors; return this; }
|
||||
public Builder garage(boolean v) { this.hasGarage = v; return this; }
|
||||
public Builder garden(boolean v) { this.hasGarden = v; return this; }
|
||||
public Builder pool(boolean v) { this.hasPool = v; return this; }
|
||||
public Builder roofType(String roofType) { this.roofType = roofType; return this; }
|
||||
public House build() { return new House(this); }
|
||||
}
|
||||
}
|
||||
20
01-creational/builder/Main.java
Normal file
20
01-creational/builder/Main.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package builder;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Builder Pattern Demo ===\n");
|
||||
|
||||
Director director = new Director();
|
||||
|
||||
House starter = director.buildStarter(new House.Builder());
|
||||
System.out.println("Starter home : " + starter);
|
||||
|
||||
House luxury = director.buildLuxury(new House.Builder());
|
||||
System.out.println("Luxury home : " + luxury);
|
||||
|
||||
// Client builds a custom house directly without the Director
|
||||
House custom = new House.Builder()
|
||||
.rooms(4).floors(2).garden(true).roofType("mansard").build();
|
||||
System.out.println("Custom home : " + custom);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/EmailNotification.java
Normal file
11
01-creational/factory-method/EmailNotification.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/EmailService.java
Normal file
11
01-creational/factory-method/EmailService.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
17
01-creational/factory-method/Main.java
Normal file
17
01-creational/factory-method/Main.java
Normal file
@@ -0,0 +1,17 @@
|
||||
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")
|
||||
};
|
||||
|
||||
for (NotificationService service : services) {
|
||||
service.notifyUser("Your order #1042 has been shipped!");
|
||||
}
|
||||
}
|
||||
}
|
||||
5
01-creational/factory-method/Notification.java
Normal file
5
01-creational/factory-method/Notification.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package factorymethod;
|
||||
|
||||
public interface Notification {
|
||||
void send(String message);
|
||||
}
|
||||
11
01-creational/factory-method/NotificationService.java
Normal file
11
01-creational/factory-method/NotificationService.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package factorymethod;
|
||||
|
||||
/** Creator - declares the factory method */
|
||||
public abstract class NotificationService {
|
||||
protected abstract Notification createNotification();
|
||||
|
||||
public void notifyUser(String message) {
|
||||
Notification n = createNotification();
|
||||
n.send(message);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/PushNotification.java
Normal file
11
01-creational/factory-method/PushNotification.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/PushService.java
Normal file
11
01-creational/factory-method/PushService.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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/SmsNotification.java
Normal file
11
01-creational/factory-method/SmsNotification.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
11
01-creational/factory-method/SmsService.java
Normal file
11
01-creational/factory-method/SmsService.java
Normal file
@@ -0,0 +1,11 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
24
01-creational/prototype/Circle.java
Normal file
24
01-creational/prototype/Circle.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package prototype;
|
||||
|
||||
public class Circle extends Shape {
|
||||
private int radius;
|
||||
|
||||
public Circle(int radius, String color) {
|
||||
this.radius = radius;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/** Copy constructor used by clone() */
|
||||
private Circle(Circle source) {
|
||||
super(source);
|
||||
this.radius = source.radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Circle clone() { return new Circle(this); }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Circle{color=" + color + ", radius=" + radius + ", pos=(" + x + "," + y + ")}";
|
||||
}
|
||||
}
|
||||
33
01-creational/prototype/Main.java
Normal file
33
01-creational/prototype/Main.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package prototype;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Prototype Pattern Demo ===\n");
|
||||
|
||||
List<Shape> originals = new ArrayList<>();
|
||||
originals.add(new Circle(10, "red"));
|
||||
originals.add(new Rectangle(20, 30, "blue"));
|
||||
|
||||
// Clone each shape - no need to know the concrete type
|
||||
List<Shape> copies = new ArrayList<>();
|
||||
for (Shape shape : originals) {
|
||||
copies.add(shape.clone());
|
||||
}
|
||||
|
||||
// Mutate copies - originals are unaffected
|
||||
copies.get(0).setColor("green");
|
||||
copies.get(0).move(5, 5);
|
||||
copies.get(1).setColor("yellow");
|
||||
|
||||
System.out.println("--- Originals ---");
|
||||
originals.forEach(System.out::println);
|
||||
|
||||
System.out.println("\n--- Clones (mutated) ---");
|
||||
copies.forEach(System.out::println);
|
||||
|
||||
System.out.println("\nSame instance? " + (originals.get(0) == copies.get(0)));
|
||||
}
|
||||
}
|
||||
26
01-creational/prototype/Rectangle.java
Normal file
26
01-creational/prototype/Rectangle.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package prototype;
|
||||
|
||||
public class Rectangle extends Shape {
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public Rectangle(int width, int height, String color) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
private Rectangle(Rectangle source) {
|
||||
super(source);
|
||||
this.width = source.width;
|
||||
this.height = source.height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle clone() { return new Rectangle(this); }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Rectangle{color=" + color + ", size=" + width + "x" + height + ", pos=(" + x + "," + y + ")}";
|
||||
}
|
||||
}
|
||||
22
01-creational/prototype/Shape.java
Normal file
22
01-creational/prototype/Shape.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package prototype;
|
||||
|
||||
/** Prototype - every shape can clone itself */
|
||||
public abstract class Shape {
|
||||
protected String color;
|
||||
protected int x;
|
||||
protected int y;
|
||||
|
||||
protected Shape(Shape source) {
|
||||
this.color = source.color;
|
||||
this.x = source.x;
|
||||
this.y = source.y;
|
||||
}
|
||||
|
||||
protected Shape() {}
|
||||
|
||||
public abstract Shape clone();
|
||||
|
||||
public void setColor(String color) { this.color = color; }
|
||||
public String getColor() { return color; }
|
||||
public void move(int x, int y) { this.x = x; this.y = y; }
|
||||
}
|
||||
34
01-creational/singleton/DatabaseConnection.java
Normal file
34
01-creational/singleton/DatabaseConnection.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package singleton;
|
||||
|
||||
/**
|
||||
* Thread-safe Singleton using double-checked locking.
|
||||
*/
|
||||
public class DatabaseConnection {
|
||||
private static volatile DatabaseConnection instance;
|
||||
private final String url;
|
||||
private int queryCount = 0;
|
||||
|
||||
private DatabaseConnection() {
|
||||
this.url = "jdbc:mysql://localhost:3306/myapp";
|
||||
System.out.println("Establishing connection to " + url);
|
||||
}
|
||||
|
||||
public static DatabaseConnection getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (DatabaseConnection.class) {
|
||||
if (instance == null) {
|
||||
instance = new DatabaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public String executeQuery(String sql) {
|
||||
queryCount++;
|
||||
return "Result #" + queryCount + " for: " + sql;
|
||||
}
|
||||
|
||||
public int getQueryCount() { return queryCount; }
|
||||
public String getUrl() { return url; }
|
||||
}
|
||||
19
01-creational/singleton/Main.java
Normal file
19
01-creational/singleton/Main.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package singleton;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Singleton Pattern Demo ===\n");
|
||||
|
||||
DatabaseConnection c1 = DatabaseConnection.getInstance();
|
||||
DatabaseConnection c2 = DatabaseConnection.getInstance();
|
||||
DatabaseConnection c3 = DatabaseConnection.getInstance();
|
||||
|
||||
System.out.println("\nAll three references same instance? " + (c1 == c2 && c2 == c3));
|
||||
|
||||
System.out.println(c1.executeQuery("SELECT * FROM users"));
|
||||
System.out.println(c2.executeQuery("SELECT * FROM orders"));
|
||||
System.out.println(c3.executeQuery("SELECT COUNT(*) FROM products"));
|
||||
|
||||
System.out.println("\nTotal queries: " + c1.getQueryCount());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user