diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Animal.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Animal.java new file mode 100644 index 0000000..a066249 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Animal.java @@ -0,0 +1,4 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public sealed interface Animal permits Cat, Dog, Fly { +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactory.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactory.java new file mode 100644 index 0000000..225e055 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactory.java @@ -0,0 +1,6 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public interface AnimalFactory { + + Animal getNewInstance(T type); +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryClassImpl.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryClassImpl.java new file mode 100644 index 0000000..0b41428 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryClassImpl.java @@ -0,0 +1,14 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public class AnimalFactoryClassImpl implements AnimalFactory> { + + @Override + public Animal getNewInstance(Class type) { + return switch (type.getSimpleName()) { + case Cat.NAME -> new Cat(); + case Dog.NAME -> new Dog(); + case Fly.NAME -> new Fly(); + default -> throw new IllegalStateException("Unexpected value: " + type.getSimpleName()); + }; + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryEnumImpl.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryEnumImpl.java new file mode 100644 index 0000000..f7b7d7e --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryEnumImpl.java @@ -0,0 +1,30 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +import java.util.function.Supplier; + +import static pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactoryEnumImpl.AnimalType; + +public class AnimalFactoryEnumImpl implements AnimalFactory { + + @Override + public Animal getNewInstance(AnimalType type) { + return type.getCreator().get(); + } + + public enum AnimalType { + DOG(() -> new Dog()), + CAT(() -> new Cat()), + FLY(() -> new Fly()); + + private final Supplier creator; + + AnimalType(Supplier creator) { + this.creator = creator; + } + + public Supplier getCreator() { + return creator; + } + } + +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryMapImpl.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryMapImpl.java new file mode 100644 index 0000000..cb77995 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryMapImpl.java @@ -0,0 +1,23 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +public class AnimalFactoryMapImpl implements AnimalFactory { + + private final Map> nameToCreator = new HashMap<>(); + + public AnimalFactoryMapImpl() { + nameToCreator.put(Fly.NAME, () -> new Fly()); + nameToCreator.put(Dog.NAME, () -> new Dog()); + nameToCreator.put(Cat.NAME, () -> new Cat()); + } + + public Animal getNewInstance(String type) { + if (nameToCreator.containsKey(type)) { + return nameToCreator.get(type).get(); + } + throw new IllegalArgumentException("There is no animal for this name " + type); + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactorySwitchExpressionImpl.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactorySwitchExpressionImpl.java new file mode 100644 index 0000000..460fc75 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactorySwitchExpressionImpl.java @@ -0,0 +1,19 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public class AnimalFactorySwitchExpressionImpl implements AnimalFactory { + + public static class Instances { + public static final Animal CAT = new Cat(); + public static final Animal DOG = new Dog(); + public static final Animal FLY = new Fly(); + } + + @Override + public Animal getNewInstance(Animal type) { + return switch (type) { + case Cat _ -> new Cat(); + case Dog _ -> new Dog(); + case Fly _ -> new Fly(); + }; + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Cat.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Cat.java new file mode 100644 index 0000000..c97868e --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Cat.java @@ -0,0 +1,11 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public record Cat() implements Animal { + + public static final String NAME = "Cat"; + + @Override + public String toString() { + return NAME; + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Dog.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Dog.java new file mode 100644 index 0000000..52b78fd --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Dog.java @@ -0,0 +1,11 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public record Dog() implements Animal { + + public static final String NAME = "Dog"; + + @Override + public String toString() { + return NAME; + } +} diff --git a/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Fly.java b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Fly.java new file mode 100644 index 0000000..f71a565 --- /dev/null +++ b/DesignPatterns/src/main/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/Fly.java @@ -0,0 +1,12 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +public record Fly() implements Animal { + + public static final String NAME = "Fly"; + + @Override + public String toString() { + return NAME; + } + +} diff --git a/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryTest.java b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryTest.java new file mode 100644 index 0000000..bd3c2cc --- /dev/null +++ b/DesignPatterns/src/test/java/pl/mperor/lab/java/design/pattern/creational/factory/basic/AnimalFactoryTest.java @@ -0,0 +1,52 @@ +package pl.mperor.lab.java.design.pattern.creational.factory.basic; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactorySwitchExpressionImpl.Instances; + +import static pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactoryEnumImpl.AnimalType; + +public class AnimalFactoryTest { + + @Test + public void animalFactoryMapImplShouldBeAbleToCreateAnimalsByNames() { + AnimalFactory factory = new AnimalFactoryMapImpl(); + Assertions.assertInstanceOf(Dog.class, factory.getNewInstance("Dog")); + Assertions.assertInstanceOf(Fly.class, factory.getNewInstance("Fly")); + Assertions.assertInstanceOf(Cat.class, factory.getNewInstance("Cat")); + + Assertions.assertNotSame(factory.getNewInstance("Dog"), factory.getNewInstance("Dog")); + Assertions.assertThrows(IllegalArgumentException.class, () -> factory.getNewInstance("Fish")); + } + + @Test + public void animalFactoryEnumImplShouldBeAbleToCreateAnimalsByEnum() { + AnimalFactory factory = new AnimalFactoryEnumImpl(); + Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(AnimalType.DOG)); + Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(AnimalType.FLY)); + Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(AnimalType.CAT)); + + Assertions.assertNotSame(factory.getNewInstance(AnimalType.DOG), factory.getNewInstance(AnimalType.DOG)); + } + + @Test + public void animalFactorySwitchExpressionImplShouldBeAbleToCreateAnimalsByAnimalInstance() { + AnimalFactory factory = new AnimalFactorySwitchExpressionImpl(); + Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(Instances.DOG)); + Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(Instances.FLY)); + Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(Instances.CAT)); + + Assertions.assertNotSame(factory.getNewInstance(Instances.DOG), factory.getNewInstance(Instances.DOG)); + } + + @Test + public void animalFactoryClassImplShouldBeAbleToCreateAnimalsByClass() { + AnimalFactory> factory = new AnimalFactoryClassImpl(); + Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(Dog.class)); + Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(Fly.class)); + Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(Cat.class)); + + Assertions.assertThrows(IllegalStateException.class, () -> factory.getNewInstance(Animal.class)); + Assertions.assertNotSame(factory.getNewInstance(Dog.class), factory.getNewInstance(Dog.class)); + } +} \ No newline at end of file