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
|
||||
|
||||
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
|
||||
|
||||
@@ -41,27 +43,16 @@ design-patterns/
|
||||
|
||||
## 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
|
||||
# Linux / macOS
|
||||
# Linux / macOS / Git Bash (Windows)
|
||||
javac 03-behavioral/strategy/*.java -d out/strategy
|
||||
java -cp out/strategy strategy.Main
|
||||
```
|
||||
|
||||
## Run all behavioral patterns (Windows)
|
||||
|
||||
Double-click `RUN-behavioral.bat` or run in PowerShell:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File run-behavioral.ps1
|
||||
```cmd
|
||||
REM Windows Command Prompt
|
||||
javac 03-behavioral\strategy\*.java -d out\strategy
|
||||
java -cp out\strategy strategy.Main
|
||||
```
|
||||
|
||||
## 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