Add all 23 GoF design pattern implementations (2026-06-13)
This commit is contained in:
50
02-structural/flyweight/Main.java
Normal file
50
02-structural/flyweight/Main.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package flyweight;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Flyweight Design Pattern — Runnable Demo
|
||||
*
|
||||
* Creates 1000 trees of only 3 species. Without Flyweight: 1000 TreeType
|
||||
* objects. With Flyweight: 3 TreeType objects (one per species), shared.
|
||||
*
|
||||
* Run: javac flyweight/*.java && java flyweight.Main
|
||||
* Article: https://ankurm.com/flyweight-design-pattern-java/
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Flyweight Design Pattern Demo ===\n");
|
||||
|
||||
List<Tree> forest = new ArrayList<>();
|
||||
Random rnd = new Random(42);
|
||||
|
||||
String[][] treeSpecs = {
|
||||
{"Oak", "dark-green", "rough-bark"},
|
||||
{"Pine", "blue-green", "needle-texture"},
|
||||
{"Birch","light-green","smooth-white-bark"}
|
||||
};
|
||||
|
||||
System.out.println("Creating 1,000 trees (only 3 TreeType objects should be created):");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
String[] spec = treeSpecs[i % 3];
|
||||
TreeType type = TreeFactory.getTreeType(spec[0], spec[1], spec[2]);
|
||||
forest.add(new Tree(rnd.nextInt(800), rnd.nextInt(600), type));
|
||||
}
|
||||
|
||||
System.out.println("\nForest created. Drawing first 5 trees:");
|
||||
for (int i = 0; i < 5; i++) {
|
||||
forest.get(i).draw();
|
||||
}
|
||||
|
||||
System.out.println("\n--- Memory summary ---");
|
||||
System.out.println("Trees in forest : " + forest.size());
|
||||
System.out.println("Unique TreeType objects in pool: " + TreeFactory.getPoolSize());
|
||||
System.out.println("Without Flyweight : 1,000 TreeType objects");
|
||||
System.out.println("With Flyweight : " + TreeFactory.getPoolSize() + " TreeType objects shared");
|
||||
|
||||
System.out.println("\n=== Demo complete ===");
|
||||
}
|
||||
}
|
||||
31
02-structural/flyweight/Tree.java
Normal file
31
02-structural/flyweight/Tree.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package flyweight;
|
||||
|
||||
/**
|
||||
* Context — stores the UNIQUE (extrinsic) state for each tree instance.
|
||||
* This is NOT the flyweight itself; it's the lightweight object that
|
||||
* holds position data and delegates rendering to a shared TreeType.
|
||||
*
|
||||
* 10,000 Tree objects × (x:4 bytes + y:4 bytes + reference:8 bytes) = ~160 KB
|
||||
* vs.
|
||||
* 10,000 Tree objects × (name + color + texture + x + y) = potentially MBs
|
||||
*/
|
||||
public class Tree {
|
||||
|
||||
// Extrinsic (unique) state — different per tree
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
// Reference to the SHARED flyweight
|
||||
private final TreeType type;
|
||||
|
||||
public Tree(int x, int y, TreeType type) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
// Passes extrinsic state (position) into the shared flyweight
|
||||
type.draw(x, y);
|
||||
}
|
||||
}
|
||||
29
02-structural/flyweight/TreeFactory.java
Normal file
29
02-structural/flyweight/TreeFactory.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package flyweight;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Flyweight Factory — the cache that ensures each unique TreeType
|
||||
* is only created once, no matter how many trees use it.
|
||||
*
|
||||
* This is the piece that makes Flyweight work:
|
||||
* it intercepts creation requests and returns an existing
|
||||
* shared instance if one already exists.
|
||||
*/
|
||||
public class TreeFactory {
|
||||
|
||||
// The pool of shared flyweights
|
||||
private static final Map<String, TreeType> treeTypes = new HashMap<>();
|
||||
|
||||
public static TreeType getTreeType(String name, String color, String texture) {
|
||||
String key = name + "_" + color + "_" + texture;
|
||||
|
||||
// Only create a new TreeType if we haven't seen this combination before
|
||||
return treeTypes.computeIfAbsent(key, k -> new TreeType(name, color, texture));
|
||||
}
|
||||
|
||||
public static int getPoolSize() {
|
||||
return treeTypes.size();
|
||||
}
|
||||
}
|
||||
29
02-structural/flyweight/TreeType.java
Normal file
29
02-structural/flyweight/TreeType.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package flyweight;
|
||||
|
||||
/**
|
||||
* Flyweight — holds the SHARED (intrinsic) state.
|
||||
* TreeType is shared between all trees of the same species.
|
||||
*
|
||||
* If you have 10,000 oak trees, there's ONE OakType object in memory.
|
||||
* Each individual tree only stores its unique position (extrinsic state).
|
||||
*/
|
||||
public class TreeType {
|
||||
|
||||
// Intrinsic (shared) state — same for all trees of this species
|
||||
private final String name;
|
||||
private final String color;
|
||||
private final String texture; // imagine a large texture bitmap here
|
||||
|
||||
public TreeType(String name, String color, String texture) {
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
this.texture = texture;
|
||||
System.out.println(" [TreeType created: " + name + "]"); // see how few are created
|
||||
}
|
||||
|
||||
// Extrinsic state (x, y) is passed IN at render time — NOT stored here
|
||||
public void draw(int x, int y) {
|
||||
System.out.printf(" Drawing %s tree [%s/%s] at (%d, %d)%n",
|
||||
name, color, texture, x, y);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user