Skip to content

Commit d0b1867

Browse files
authored
Add factory implementations with test scenario (#47)
1 parent ed65563 commit d0b1867

File tree

10 files changed

+182
-0
lines changed

10 files changed

+182
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public sealed interface Animal permits Cat, Dog, Fly {
4+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public interface AnimalFactory<T> {
4+
5+
Animal getNewInstance(T type);
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public class AnimalFactoryClassImpl implements AnimalFactory<Class<? extends Animal>> {
4+
5+
@Override
6+
public Animal getNewInstance(Class<? extends Animal> type) {
7+
return switch (type.getSimpleName()) {
8+
case Cat.NAME -> new Cat();
9+
case Dog.NAME -> new Dog();
10+
case Fly.NAME -> new Fly();
11+
default -> throw new IllegalStateException("Unexpected value: " + type.getSimpleName());
12+
};
13+
}
14+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
import java.util.function.Supplier;
4+
5+
import static pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactoryEnumImpl.AnimalType;
6+
7+
public class AnimalFactoryEnumImpl implements AnimalFactory<AnimalType> {
8+
9+
@Override
10+
public Animal getNewInstance(AnimalType type) {
11+
return type.getCreator().get();
12+
}
13+
14+
public enum AnimalType {
15+
DOG(() -> new Dog()),
16+
CAT(() -> new Cat()),
17+
FLY(() -> new Fly());
18+
19+
private final Supplier<Animal> creator;
20+
21+
AnimalType(Supplier<Animal> creator) {
22+
this.creator = creator;
23+
}
24+
25+
public Supplier<Animal> getCreator() {
26+
return creator;
27+
}
28+
}
29+
30+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.function.Supplier;
6+
7+
public class AnimalFactoryMapImpl implements AnimalFactory<String> {
8+
9+
private final Map<String, Supplier<Animal>> nameToCreator = new HashMap<>();
10+
11+
public AnimalFactoryMapImpl() {
12+
nameToCreator.put(Fly.NAME, () -> new Fly());
13+
nameToCreator.put(Dog.NAME, () -> new Dog());
14+
nameToCreator.put(Cat.NAME, () -> new Cat());
15+
}
16+
17+
public Animal getNewInstance(String type) {
18+
if (nameToCreator.containsKey(type)) {
19+
return nameToCreator.get(type).get();
20+
}
21+
throw new IllegalArgumentException("There is no animal for this name " + type);
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public class AnimalFactorySwitchExpressionImpl implements AnimalFactory<Animal> {
4+
5+
public static class Instances {
6+
public static final Animal CAT = new Cat();
7+
public static final Animal DOG = new Dog();
8+
public static final Animal FLY = new Fly();
9+
}
10+
11+
@Override
12+
public Animal getNewInstance(Animal type) {
13+
return switch (type) {
14+
case Cat _ -> new Cat();
15+
case Dog _ -> new Dog();
16+
case Fly _ -> new Fly();
17+
};
18+
}
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public record Cat() implements Animal {
4+
5+
public static final String NAME = "Cat";
6+
7+
@Override
8+
public String toString() {
9+
return NAME;
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public record Dog() implements Animal {
4+
5+
public static final String NAME = "Dog";
6+
7+
@Override
8+
public String toString() {
9+
return NAME;
10+
}
11+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
public record Fly() implements Animal {
4+
5+
public static final String NAME = "Fly";
6+
7+
@Override
8+
public String toString() {
9+
return NAME;
10+
}
11+
12+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package pl.mperor.lab.java.design.pattern.creational.factory.basic;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
import pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactorySwitchExpressionImpl.Instances;
6+
7+
import static pl.mperor.lab.java.design.pattern.creational.factory.basic.AnimalFactoryEnumImpl.AnimalType;
8+
9+
public class AnimalFactoryTest {
10+
11+
@Test
12+
public void animalFactoryMapImplShouldBeAbleToCreateAnimalsByNames() {
13+
AnimalFactory<String> factory = new AnimalFactoryMapImpl();
14+
Assertions.assertInstanceOf(Dog.class, factory.getNewInstance("Dog"));
15+
Assertions.assertInstanceOf(Fly.class, factory.getNewInstance("Fly"));
16+
Assertions.assertInstanceOf(Cat.class, factory.getNewInstance("Cat"));
17+
18+
Assertions.assertNotSame(factory.getNewInstance("Dog"), factory.getNewInstance("Dog"));
19+
Assertions.assertThrows(IllegalArgumentException.class, () -> factory.getNewInstance("Fish"));
20+
}
21+
22+
@Test
23+
public void animalFactoryEnumImplShouldBeAbleToCreateAnimalsByEnum() {
24+
AnimalFactory<AnimalType> factory = new AnimalFactoryEnumImpl();
25+
Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(AnimalType.DOG));
26+
Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(AnimalType.FLY));
27+
Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(AnimalType.CAT));
28+
29+
Assertions.assertNotSame(factory.getNewInstance(AnimalType.DOG), factory.getNewInstance(AnimalType.DOG));
30+
}
31+
32+
@Test
33+
public void animalFactorySwitchExpressionImplShouldBeAbleToCreateAnimalsByAnimalInstance() {
34+
AnimalFactory<Animal> factory = new AnimalFactorySwitchExpressionImpl();
35+
Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(Instances.DOG));
36+
Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(Instances.FLY));
37+
Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(Instances.CAT));
38+
39+
Assertions.assertNotSame(factory.getNewInstance(Instances.DOG), factory.getNewInstance(Instances.DOG));
40+
}
41+
42+
@Test
43+
public void animalFactoryClassImplShouldBeAbleToCreateAnimalsByClass() {
44+
AnimalFactory<Class<? extends Animal>> factory = new AnimalFactoryClassImpl();
45+
Assertions.assertInstanceOf(Dog.class, factory.getNewInstance(Dog.class));
46+
Assertions.assertInstanceOf(Fly.class, factory.getNewInstance(Fly.class));
47+
Assertions.assertInstanceOf(Cat.class, factory.getNewInstance(Cat.class));
48+
49+
Assertions.assertThrows(IllegalStateException.class, () -> factory.getNewInstance(Animal.class));
50+
Assertions.assertNotSame(factory.getNewInstance(Dog.class), factory.getNewInstance(Dog.class));
51+
}
52+
}

0 commit comments

Comments
 (0)