From b959f7e1210af6e01514b0292ac654772fee4412 Mon Sep 17 00:00:00 2001 From: mperor Date: Thu, 9 Jan 2025 22:58:55 +0100 Subject: [PATCH] Add lightweight example with test --- .../structural/flyweight/GameWorld.java | 51 +++++++++++++++++++ .../flyweight/terrain/GrassTexture.java | 4 ++ .../flyweight/terrain/SandTexture.java | 4 ++ .../structural/flyweight/terrain/Terrain.java | 31 +++++++++++ .../flyweight/terrain/TerrainTexture.java | 4 ++ .../flyweight/terrain/WaterTexture.java | 4 ++ .../structural/flyweight/GameWorldTest.java | 24 +++++++++ 7 files changed, 122 insertions(+) create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorld.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/GrassTexture.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/SandTexture.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/Terrain.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/TerrainTexture.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/WaterTexture.java create mode 100644 DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorldTest.java diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorld.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorld.java new file mode 100644 index 0000000..0c3ff97 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorld.java @@ -0,0 +1,51 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight; + +import pl.mperor.lab.java.design.pattern.structural.flyweight.terrain.Terrain; + +import java.util.Arrays; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +public class GameWorld { + + private final int width; + private final int height; + private final Terrain[][] tiles; + + public GameWorld(int width, int height) { + assert width >= 0; + assert height >= 0; + + this.width = width; + this.height = height; + this.tiles = generateTiles(); + } + + private Terrain[][] generateTiles() { + Terrain[][] tiles = new Terrain[width][height]; + ThreadLocalRandom random = ThreadLocalRandom.current(); + Terrain[] terrains = Terrain.values(); + + for (int x = 0; x < tiles.length; x++) { + for (int y = 0; y < tiles[0].length; y++) { + tiles[x][y] = terrains[random.nextInt(terrains.length)]; + } + } + + return tiles; + } + + public Terrain getTiles(int x, int y) { + assert x >= 0 && x < tiles.length ; + assert y >= 0 && y < tiles[0].length; + + return tiles[x][y]; + } + + @Override + public String toString() { + return Arrays.stream(tiles) + .map(Arrays::toString) + .collect(Collectors.joining(System.lineSeparator())); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/GrassTexture.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/GrassTexture.java new file mode 100644 index 0000000..2de16de --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/GrassTexture.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight.terrain; + +public record GrassTexture() implements TerrainTexture { +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/SandTexture.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/SandTexture.java new file mode 100644 index 0000000..0f0f45c --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/SandTexture.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight.terrain; + +public record SandTexture() implements TerrainTexture { +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/Terrain.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/Terrain.java new file mode 100644 index 0000000..69544a7 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/Terrain.java @@ -0,0 +1,31 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight.terrain; + +public enum Terrain { + + WATER("W", new WaterTexture(), 1), + SAND("S", new SandTexture(), 2), + GRASS("G", new GrassTexture(), 3); + + private final String name; + private final TerrainTexture terrainTexture; + private final int movementCost; + + Terrain(String name, TerrainTexture terrainTexture, int movementCost) { + this.name = name; + this.terrainTexture = terrainTexture; + this.movementCost = movementCost; + } + + public TerrainTexture getTerrainTexture() { + return terrainTexture; + } + + public int getMovementCost() { + return movementCost; + } + + @Override + public String toString() { + return name; + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/TerrainTexture.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/TerrainTexture.java new file mode 100644 index 0000000..9524673 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/TerrainTexture.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight.terrain; + +public sealed interface TerrainTexture permits GrassTexture, SandTexture, WaterTexture { +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/WaterTexture.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/WaterTexture.java new file mode 100644 index 0000000..a728251 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/flyweight/terrain/WaterTexture.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight.terrain; + +public record WaterTexture() implements TerrainTexture { +} diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorldTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorldTest.java new file mode 100644 index 0000000..98e908f --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/flyweight/GameWorldTest.java @@ -0,0 +1,24 @@ +package pl.mperor.lab.java.design.pattern.structural.flyweight; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pl.mperor.lab.java.design.pattern.structural.flyweight.terrain.Terrain; + +import java.util.Arrays; + + +public class GameWorldTest { + + @Test + public void testCreatedGameWorldContainsOnlyTerrainTilesWithTheSameTexture() { + GameWorld gw = new GameWorld(20, 20); + System.out.println(gw); + Terrain firstTile = gw.getTiles(0, 0); + + Assertions.assertTrue(Arrays.stream(Terrain.values()) + .map(Terrain::getTerrainTexture) + .anyMatch(texture -> texture == firstTile.getTerrainTexture()), + "The same instance is used for the terrain texture!"); + } + +} \ No newline at end of file