@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));