@Nori 가 이번 주에 질문주셨던 내용으로 enum 에 관한 내용이 있었는데, 이를 활용하여 팩토리 메서드를 구현해봤다.
public class Triangle implements Figure {
private List<Integer> points;
public Triangle(List<Integer> points) {
this.points = points;
}
@Override
public List<Integer> getPoints() {
return points;
}
}
Figure 를 구현한 Line, Triangle, Rectangle 클래스의 인스턴스를 생성하여 반환해주는 메서드를 enum 을 활용하여 구현해보자.
Line, Triangle, Rectangle 을 각각 구별할 수 있는 상태 값은?
정점(vertex)의 개수다. (Line: 2개, Triangle: 3개, Rectangle: 4개)편의상 정점을 x, y 좌표가 아닌 해당 정점의 인덱스 값을 나타내는 Integer 타입이라 가정한다.
List에 정점 인덱스를 담아 팩토리 메서드의 파라미터로 전달하면?
이 팩토리 메서드를 enum 클래스의 인스턴스 메서드로 구현해보자
enum 클래스는 어떤 타입의 상수를 가져야할까?
팩토리 메서드에 주어지는 인자에 따라 생성자를 달리하여 인스턴스를 생성하기 위해서 어떤 작업을 수행해야할까?
리플렉션을 사용하자
리플렉션이란? 구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API
그렇다. enum 클래스는 생성하고자하는 (패키지.)클래스의 이름, 즉 String 타입 변수만 지니고 있으면 된다.
// enum 클래스 - Shape
RECTANGLE("Rectangle"),
TRIANGLE("Triangle"),
LINE("Line");
// enum 클래스 내의 팩토리 메서드
static Figure of(List<Object> points) throws ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, InstantiationException, IllegalAccessException {
Shape[] shapes = Shape.values();
Class<?> clazz = Class.forName(shapes[shapes.length + 1 - points.size()].className);
Constructor<?> constructors = clazz.getConstructor(List.class);
return (Figure) constructors.newInstance(points);
}
// main
Object shape1 = Shape.of(List.of(1, 2));
Object shape2 = Shape.of(List.of(1, 2, 3));
Object shape3 = Shape.of(List.of(1, 2, 3, 4));
System.out.println(shape1.getClass().getName() + " " +
shape1.getClass().getMethod("getPoints").invoke(shape1));
System.out.println(shape2.getClass().getName() + " " +
shape2.getClass().getMethod("getPoints").invoke(shape2));
System.out.println(shape3.getClass().getName() + " " +
shape3.getClass().getMethod("getPoints").invoke(shape3));
