Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package pl.mperor.lab.java.design.pattern.creational.factory.basic;

public sealed interface Animal permits Cat, Dog, Fly {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package pl.mperor.lab.java.design.pattern.creational.factory.basic;

public interface AnimalFactory<T> {

Animal getNewInstance(T type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package pl.mperor.lab.java.design.pattern.creational.factory.basic;

public class AnimalFactoryClassImpl implements AnimalFactory<Class<? extends Animal>> {

@Override
public Animal getNewInstance(Class<? extends Animal> 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());
};
}
}
Original file line number Diff line number Diff line change
@@ -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<AnimalType> {

@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<Animal> creator;

AnimalType(Supplier<Animal> creator) {
this.creator = creator;
}

public Supplier<Animal> getCreator() {
return creator;
}
}

}
Original file line number Diff line number Diff line change
@@ -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<String> {

private final Map<String, Supplier<Animal>> 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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package pl.mperor.lab.java.design.pattern.creational.factory.basic;

public class AnimalFactorySwitchExpressionImpl implements AnimalFactory<Animal> {

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();
};
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}

}
Original file line number Diff line number Diff line change
@@ -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<String> 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<AnimalType> 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<Animal> 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<Class<? extends Animal>> 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));
}
}
Loading