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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
powershell -ExecutionPolicy Bypass -NoExit -File "%~dp0push-to-gitea.ps1"
|
|
||||||
25
README.md
25
README.md
@@ -1,6 +1,8 @@
|
|||||||
# GoF Design Patterns in Java
|
# GoF Design Patterns in Java
|
||||||
|
|
||||||
Complete runnable Java 17 implementations of all 23 Gang of Four design patterns. Each pattern has a dedicated article at [ankurm.com](https://ankurm.com/gof-design-patterns-java/) with a UML diagram, step-by-step explanation, and console output.
|
Complete runnable Java 17 implementations of all 23 Gang of Four design patterns.
|
||||||
|
Each pattern has a dedicated article at [ankurm.com](https://ankurm.com/gof-design-patterns-java/)
|
||||||
|
with a UML diagram, step-by-step explanation, and console output.
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
@@ -41,27 +43,16 @@ design-patterns/
|
|||||||
|
|
||||||
## Run any pattern
|
## Run any pattern
|
||||||
|
|
||||||
```powershell
|
|
||||||
# Windows (PowerShell)
|
|
||||||
$JAVAC = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\javac.exe'
|
|
||||||
$JAVA = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\java.exe'
|
|
||||||
|
|
||||||
& $JAVAC 03-behavioral/strategy/*.java -d out/strategy
|
|
||||||
& $JAVA -cp out/strategy strategy.Main
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Linux / macOS
|
# Linux / macOS / Git Bash (Windows)
|
||||||
javac 03-behavioral/strategy/*.java -d out/strategy
|
javac 03-behavioral/strategy/*.java -d out/strategy
|
||||||
java -cp out/strategy strategy.Main
|
java -cp out/strategy strategy.Main
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run all behavioral patterns (Windows)
|
```cmd
|
||||||
|
REM Windows Command Prompt
|
||||||
Double-click `RUN-behavioral.bat` or run in PowerShell:
|
javac 03-behavioral\strategy\*.java -d out\strategy
|
||||||
|
java -cp out\strategy strategy.Main
|
||||||
```powershell
|
|
||||||
powershell -ExecutionPolicy Bypass -File run-behavioral.ps1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Articles
|
## Articles
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
powershell -ExecutionPolicy Bypass -NoExit -Command "& 'C:\Users\Ankur\Claude\Projects\@ankurm Blog\design-patterns\run-behavioral.ps1'"
|
|
||||||
2
RUN.bat
2
RUN.bat
@@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
powershell -ExecutionPolicy Bypass -NoExit -Command "& 'C:\Users\Ankur\Claude\Projects\@ankurm Blog\design-patterns\run-structural.ps1'"
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
@echo off
|
|
||||||
setlocal
|
|
||||||
|
|
||||||
set BASE=%~dp0
|
|
||||||
set OUT=%BASE%\out
|
|
||||||
|
|
||||||
echo ============================================================
|
|
||||||
echo Compiling and running structural design pattern examples
|
|
||||||
echo ============================================================
|
|
||||||
|
|
||||||
:: Create output dir
|
|
||||||
if not exist "%OUT%" mkdir "%OUT%"
|
|
||||||
|
|
||||||
:: --- Adapter ---
|
|
||||||
echo.
|
|
||||||
echo [1/7] ADAPTER
|
|
||||||
javac -d "%OUT%\adapter" -sourcepath "%BASE%\02-structural\adapter" "%BASE%\02-structural\adapter\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Adapter) else (
|
|
||||||
java -cp "%OUT%\adapter" adapter.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Bridge ---
|
|
||||||
echo.
|
|
||||||
echo [2/7] BRIDGE
|
|
||||||
javac -d "%OUT%\bridge" -sourcepath "%BASE%\02-structural\bridge" "%BASE%\02-structural\bridge\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Bridge) else (
|
|
||||||
java -cp "%OUT%\bridge" bridge.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Composite ---
|
|
||||||
echo.
|
|
||||||
echo [3/7] COMPOSITE
|
|
||||||
javac -d "%OUT%\composite" -sourcepath "%BASE%\02-structural\composite" "%BASE%\02-structural\composite\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Composite) else (
|
|
||||||
java -cp "%OUT%\composite" composite.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Decorator ---
|
|
||||||
echo.
|
|
||||||
echo [4/7] DECORATOR
|
|
||||||
javac -d "%OUT%\decorator" -sourcepath "%BASE%\02-structural\decorator" "%BASE%\02-structural\decorator\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Decorator) else (
|
|
||||||
java -cp "%OUT%\decorator" decorator.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Facade ---
|
|
||||||
echo.
|
|
||||||
echo [5/7] FACADE
|
|
||||||
javac -d "%OUT%\facade" -sourcepath "%BASE%\02-structural\facade" "%BASE%\02-structural\facade\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Facade) else (
|
|
||||||
java -cp "%OUT%\facade" facade.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Flyweight ---
|
|
||||||
echo.
|
|
||||||
echo [6/7] FLYWEIGHT
|
|
||||||
javac -d "%OUT%\flyweight" -sourcepath "%BASE%\02-structural\flyweight" "%BASE%\02-structural\flyweight\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Flyweight) else (
|
|
||||||
java -cp "%OUT%\flyweight" flyweight.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
:: --- Proxy ---
|
|
||||||
echo.
|
|
||||||
echo [7/7] PROXY
|
|
||||||
javac -d "%OUT%\proxy" -sourcepath "%BASE%\02-structural\proxy" "%BASE%\02-structural\proxy\*.java" 2>&1
|
|
||||||
if errorlevel 1 (echo COMPILE ERROR - Proxy) else (
|
|
||||||
java -cp "%OUT%\proxy" proxy.Main
|
|
||||||
)
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ============================================================
|
|
||||||
echo All structural patterns compiled and executed
|
|
||||||
echo ============================================================
|
|
||||||
pause
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
$REMOTE = "https://ankurm.com/git.app/asmhatre/design-patterns.git"
|
|
||||||
$BRANCH = "main"
|
|
||||||
|
|
||||||
Set-Location $PSScriptRoot
|
|
||||||
|
|
||||||
# Always run git init - it is safe and idempotent on an existing repo
|
|
||||||
git init
|
|
||||||
|
|
||||||
# Configure remote
|
|
||||||
$existing = git remote get-url origin 2>$null
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
git remote add origin $REMOTE
|
|
||||||
Write-Host "Added remote." -ForegroundColor Green
|
|
||||||
} elseif ($existing.Trim() -ne $REMOTE) {
|
|
||||||
git remote set-url origin $REMOTE
|
|
||||||
Write-Host "Updated remote." -ForegroundColor Yellow
|
|
||||||
} else {
|
|
||||||
Write-Host "Remote OK: $REMOTE" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create .gitignore if missing
|
|
||||||
if (-not (Test-Path ".gitignore")) {
|
|
||||||
Set-Content ".gitignore" "out/`n*.class`nscreenshots/*.png`n*.b64.txt"
|
|
||||||
Write-Host "Created .gitignore" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
|
|
||||||
# Stage and commit
|
|
||||||
git add -A
|
|
||||||
$status = git status --short
|
|
||||||
|
|
||||||
if (-not $status) {
|
|
||||||
Write-Host "Nothing to commit - repo is up to date." -ForegroundColor Cyan
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`nFiles to commit:" -ForegroundColor Yellow
|
|
||||||
Write-Host $status
|
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd"
|
|
||||||
git commit -m "Add all 23 GoF design pattern implementations ($timestamp)"
|
|
||||||
|
|
||||||
Write-Host "`nPushing to $REMOTE ..." -ForegroundColor Yellow
|
|
||||||
git push -u origin $BRANCH
|
|
||||||
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Host "`nDone! Code live at $REMOTE" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "`nPush failed. Try manually: git push -u origin main" -ForegroundColor Red
|
|
||||||
Write-Host "If prompted, enter your Gitea username and password." -ForegroundColor Yellow
|
|
||||||
}
|
|
||||||
80
run-all.bat
80
run-all.bat
@@ -1,80 +0,0 @@
|
|||||||
@echo off
|
|
||||||
setlocal EnableDelayedExpansion
|
|
||||||
|
|
||||||
set BASE=%~dp0
|
|
||||||
set JAVAC="C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\javac.exe"
|
|
||||||
set JAVA="C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\java.exe"
|
|
||||||
set LOG=%BASE%output.log
|
|
||||||
|
|
||||||
echo Design Patterns - Compile and Run > "%LOG%"
|
|
||||||
echo Java: 17.0.7 (Eclipse Temurin) >> "%LOG%"
|
|
||||||
echo ================================ >> "%LOG%"
|
|
||||||
|
|
||||||
:: Create output dirs
|
|
||||||
for %%P in (adapter bridge composite decorator facade flyweight proxy) do (
|
|
||||||
if not exist "%BASE%out\%%P" mkdir "%BASE%out\%%P"
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Function-like subroutine to compile a package
|
|
||||||
:: Usage: CALL :compile_pkg <package> <relative_src_dir>
|
|
||||||
|
|
||||||
:: --- ADAPTER ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === ADAPTER === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\adapter\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\adapter" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\adapter" adapter.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- BRIDGE ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === BRIDGE === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\bridge\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\bridge" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\bridge" bridge.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- COMPOSITE ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === COMPOSITE === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\composite\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\composite" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\composite" composite.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- DECORATOR ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === DECORATOR === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\decorator\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\decorator" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\decorator" decorator.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- FACADE ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === FACADE === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\facade\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\facade" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\facade" facade.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- FLYWEIGHT ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === FLYWEIGHT === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\flyweight\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\flyweight" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\flyweight" flyweight.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
:: --- PROXY ---
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo === PROXY === >> "%LOG%"
|
|
||||||
set FILES=
|
|
||||||
for %%f in ("%BASE%02-structural\proxy\*.java") do set FILES=!FILES! "%%f"
|
|
||||||
%JAVAC% -d "%BASE%out\proxy" !FILES! >> "%LOG%" 2>&1
|
|
||||||
if not errorlevel 1 (%JAVA% -cp "%BASE%out\proxy" proxy.Main >> "%LOG%" 2>&1)
|
|
||||||
|
|
||||||
echo. >> "%LOG%"
|
|
||||||
echo [DONE] >> "%LOG%"
|
|
||||||
|
|
||||||
notepad "%LOG%"
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
$JAVAC = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\javac.exe'
|
|
||||||
$JAVA = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\java.exe'
|
|
||||||
$BASE = 'C:\Users\Ankur\Claude\Projects\@ankurm Blog\design-patterns'
|
|
||||||
$OUTDIR = "$BASE\screenshots"
|
|
||||||
|
|
||||||
New-Item -Force -ItemType Directory $OUTDIR | Out-Null
|
|
||||||
|
|
||||||
$patterns = @(
|
|
||||||
@{dir="chain-of-responsibility"; pkg="chain"; main="chain.Main"},
|
|
||||||
@{dir="command"; pkg="command"; main="command.Main"},
|
|
||||||
@{dir="iterator"; pkg="iterator"; main="iterator.Main"},
|
|
||||||
@{dir="mediator"; pkg="mediator"; main="mediator.Main"},
|
|
||||||
@{dir="memento"; pkg="memento"; main="memento.Main"},
|
|
||||||
@{dir="observer"; pkg="observer"; main="observer.Main"},
|
|
||||||
@{dir="state"; pkg="state"; main="state.Main"},
|
|
||||||
@{dir="strategy"; pkg="strategy"; main="strategy.Main"},
|
|
||||||
@{dir="template-method"; pkg="template"; main="template.Main"},
|
|
||||||
@{dir="visitor"; pkg="visitor"; main="visitor.Main"}
|
|
||||||
)
|
|
||||||
|
|
||||||
$allOk = $true
|
|
||||||
|
|
||||||
foreach ($p in $patterns) {
|
|
||||||
$label = $p.dir.ToUpper()
|
|
||||||
Write-Host "`n=== $label ===" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
$srcDir = "$BASE\03-behavioral\$($p.dir)"
|
|
||||||
$outDir = "$BASE\out\$($p.pkg)"
|
|
||||||
New-Item -Force -ItemType Directory $outDir | Out-Null
|
|
||||||
|
|
||||||
$files = @(Get-ChildItem "$srcDir\*.java" | Select-Object -ExpandProperty FullName)
|
|
||||||
|
|
||||||
if ($files.Count -eq 0) {
|
|
||||||
Write-Host "[SKIP] No .java files in $srcDir" -ForegroundColor Yellow
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
$compileOut = & $JAVAC -d $outDir @files 2>&1
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
Write-Host "[FAIL] $label compile error:" -ForegroundColor Red
|
|
||||||
$compileOut | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
|
|
||||||
$allOk = $false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "[OK] Compiled $($p.dir)" -ForegroundColor Green
|
|
||||||
|
|
||||||
$logFile = "$OUTDIR\$($p.pkg)-output.txt"
|
|
||||||
$runOut = & $JAVA -cp $outDir $($p.main) 2>&1
|
|
||||||
$runOut | Out-File -FilePath $logFile -Encoding utf8
|
|
||||||
$runOut | ForEach-Object { Write-Host $_ }
|
|
||||||
Write-Host "[SAVED] $logFile" -ForegroundColor DarkGray
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`n============================================" -ForegroundColor Yellow
|
|
||||||
if ($allOk) {
|
|
||||||
Write-Host "All 10 behavioral patterns compiled and ran OK" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "Some patterns had errors - check output above" -ForegroundColor Red
|
|
||||||
}
|
|
||||||
Write-Host "Output files: $OUTDIR" -ForegroundColor Yellow
|
|
||||||
Read-Host "`nPress Enter to close"
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
$JAVAC = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\javac.exe'
|
|
||||||
$JAVA = 'C:\Program Files\Eclipse Adoptium\jdk-17.0.7.7-hotspot\bin\java.exe'
|
|
||||||
$BASE = 'C:\Users\Ankur\Claude\Projects\@ankurm Blog\design-patterns'
|
|
||||||
$OUTDIR = "$BASE\screenshots"
|
|
||||||
|
|
||||||
New-Item -Force -ItemType Directory $OUTDIR | Out-Null
|
|
||||||
|
|
||||||
$patterns = @(
|
|
||||||
@{dir="adapter"; main="adapter.Main"},
|
|
||||||
@{dir="bridge"; main="bridge.Main"},
|
|
||||||
@{dir="composite"; main="composite.Main"},
|
|
||||||
@{dir="decorator"; main="decorator.Main"},
|
|
||||||
@{dir="facade"; main="facade.Main"},
|
|
||||||
@{dir="flyweight"; main="flyweight.Main"},
|
|
||||||
@{dir="proxy"; main="proxy.Main"}
|
|
||||||
)
|
|
||||||
|
|
||||||
$allOk = $true
|
|
||||||
|
|
||||||
foreach ($p in $patterns) {
|
|
||||||
$label = $p.dir.ToUpper()
|
|
||||||
Write-Host "`n=== $label ===" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
$srcDir = "$BASE\02-structural\$($p.dir)"
|
|
||||||
$outDir = "$BASE\out\$($p.dir)"
|
|
||||||
New-Item -Force -ItemType Directory $outDir | Out-Null
|
|
||||||
|
|
||||||
$files = @(Get-ChildItem "$srcDir\*.java" | Select-Object -ExpandProperty FullName)
|
|
||||||
|
|
||||||
if ($files.Count -eq 0) {
|
|
||||||
Write-Host "[SKIP] No .java files in $srcDir" -ForegroundColor Yellow
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compile
|
|
||||||
$compileOut = & $JAVAC -d $outDir @files 2>&1
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
Write-Host "[FAIL] $label compile error:" -ForegroundColor Red
|
|
||||||
$compileOut | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
|
|
||||||
$allOk = $false
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "[OK] Compiled $($p.dir)" -ForegroundColor Green
|
|
||||||
|
|
||||||
# Run and save to per-pattern file
|
|
||||||
$logFile = "$OUTDIR\$($p.dir)-output.txt"
|
|
||||||
$runOut = & $JAVA -cp $outDir $($p.main) 2>&1
|
|
||||||
$runOut | Out-File -FilePath $logFile -Encoding utf8
|
|
||||||
$runOut | ForEach-Object { Write-Host $_ }
|
|
||||||
Write-Host "[SAVED] $logFile" -ForegroundColor DarkGray
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`n============================================" -ForegroundColor Yellow
|
|
||||||
if ($allOk) {
|
|
||||||
Write-Host "All 7 structural patterns compiled and ran OK" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "Some patterns had errors - check output above" -ForegroundColor Red
|
|
||||||
}
|
|
||||||
Write-Host "Output files: $OUTDIR" -ForegroundColor Yellow
|
|
||||||
Read-Host "`nPress Enter to close"
|
|
||||||
Reference in New Issue
Block a user