From f317b97335d33886582b3027e9970ac45928f738 Mon Sep 17 00:00:00 2001 From: mperor Date: Sat, 18 Jan 2025 15:48:21 +0100 Subject: [PATCH] Add ability tree composite implementation --- .../pattern/structural/composite/Ability.java | 17 +++++++++ .../structural/composite/AbilityUtils.java | 25 +++++++++++++ .../structural/composite/ComplexAbility.java | 20 +++++++++++ .../structural/composite/SimpleAbility.java | 4 +++ .../composite/AbilityTreeCompositeTest.java | 36 +++++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Ability.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityUtils.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/ComplexAbility.java create mode 100644 DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/SimpleAbility.java create mode 100644 DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityTreeCompositeTest.java diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Ability.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Ability.java new file mode 100644 index 0000000..3008638 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/Ability.java @@ -0,0 +1,17 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +public interface Ability { + + String name(); + + int value(); + + static Ability of(String name, int value) { + return new SimpleAbility(name, value); + } + + static Ability of(String name, Ability... abilities) { + return new ComplexAbility(name, abilities); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityUtils.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityUtils.java new file mode 100644 index 0000000..9a23fcf --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityUtils.java @@ -0,0 +1,25 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import java.util.stream.Collectors; + +public class AbilityUtils { + + private AbilityUtils() { + } + + public static void printAbilityTree(Ability root) { + System.out.println(printAbilityTree(root, 0)); + } + + private static String printAbilityTree(Ability ability, int level) { + var nested = ""; + if (ability instanceof ComplexAbility ca) { + nested = ca.abilities().stream() + .map(a -> printAbilityTree(a, level + 1)) + .collect(Collectors.joining()); + } + + return "%s%s (%d)%n%s".formatted(" ".repeat(level), ability.name(), ability.value(), nested); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/ComplexAbility.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/ComplexAbility.java new file mode 100644 index 0000000..35916df --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/ComplexAbility.java @@ -0,0 +1,20 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import java.util.Arrays; +import java.util.List; + +public record ComplexAbility(String name, List abilities) implements Ability { + + public ComplexAbility(String name, Ability... abilities) { + this(name, Arrays.asList(abilities)); + } + + @Override + public int value() { + return (int) abilities.stream() + .mapToInt(Ability::value) + .average() + .orElse(0); + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/SimpleAbility.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/SimpleAbility.java new file mode 100644 index 0000000..97bc825 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/structural/composite/SimpleAbility.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +public record SimpleAbility(String name, int value) implements Ability { +} diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityTreeCompositeTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityTreeCompositeTest.java new file mode 100644 index 0000000..9dbdeac --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/structural/composite/AbilityTreeCompositeTest.java @@ -0,0 +1,36 @@ +package pl.mperor.lab.java.design.pattern.structural.composite; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class AbilityTreeCompositeTest { + + @Test + public void testCreateAbilityTree() { + var physicalHealth = Ability.of("Physical Health", + Ability.of("Fitness", + Ability.of("Jogging", 20), + Ability.of("Stretching", 40), + Ability.of("Swimming", 60) + ), + Ability.of("Sleep", 50), + Ability.of("Nutrition", 30) + ); + Assertions.assertEquals(40, physicalHealth.value()); + + var mentalHealth = Ability.of("Mental Health", + Ability.of("Stress Management", 50) + ); + Assertions.assertEquals(50, mentalHealth.value()); + + var lifeAndHealth = Ability.of("Life and Health", + physicalHealth, + mentalHealth, + Ability.of("Social Skills", 30) + ); + Assertions.assertEquals(40, lifeAndHealth.value()); + + AbilityUtils.printAbilityTree(lifeAndHealth); + } + +} \ No newline at end of file