[Java] enum 과 팩토리 메서드

naneun·2022년 2월 26일
0

Java

목록 보기
4/7
post-thumbnail

✨ enum 을 활용한 팩토리 메서드

 @Nori 가 이번 주에 질문주셨던 내용으로 enum 에 관한 내용이 있었는데, 이를 활용하여 팩토리 메서드를 구현해봤다.

  • 🔰 팩토리 메서드

    • 특정 클래스의 인스턴스는 물론 리턴 타입의 하위 타입의 인스턴스를 모두 리턴할 수 있는 메서드
  • 💤 생각의 흐름

    SmartSelectImage_2022-02-27-03-53-45

    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에 정점 인덱스를 담아 팩토리 메서드의 파라미터로 전달하면?

      • List의 size 개수로 생성할 인스턴스를 결정할 수 있다.
    • 이 팩토리 메서드를 enum 클래스의 인스턴스 메서드로 구현해보자

    • enum 클래스는 어떤 타입의 상수를 가져야할까?

      • Figure 타입의 변수를 둘까? -> enum 클래스는 상수 클래스다. Figure 타입의 변수를 둔다면 최초 생성된 인스턴스만 저장하고 꺼내쓸 수 있다. 따라서, 팩토리 메서드와 부합하지 않다.
    • 팩토리 메서드에 주어지는 인자에 따라 생성자를 달리하여 인스턴스를 생성하기 위해서 어떤 작업을 수행해야할까?

      • 리플렉션을 사용하자

      • 리플렉션이란? 구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 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));

        SmartSelectImage_2022-02-27-04-36-53

profile
riako

0개의 댓글