TIL - 0711

java-ims

내부 flow

  1. Request 메세지 파싱
  2. Request 객체 생성
  3. Request에 핸들러(컨트롤러) 요청 : path를 가지고 있기때문에 위임
  4. 컨트롤러에 Request 넘겨주며 처리 요청
  5. ResponseEntity(HttpMethod, Header, Body) 생성
  6. Response 객체 응답하기

Response 작성할 때 필요한 데이터를 가진 ResponseEntity 만들기

  • 빌더 패턴으로 만들기
    • 장점 : 조립하듯이 객체를 생성할 수 있음, 객체 생성 시 설정해야할 필드가 많아지면서 선택적으로 필드를 설정할 수 있게할 때 좋음(유연성), 특정 필드만 깔끔하게 기본값을 설정해둘 수 있음, 필드 각각의 할당 조건이 생길 때 분리해두면 코드가 간결해지는 효과를 볼 수 있음
public class ResponseEntity {
    private HttpStatus status;
    // TODO : 헤더를 만들어야함
    private String body;
    
    private ResponseEntity(HttpStatus status, String body) {
        this.status = status;
        this.body = body;
    }
    
    
    public static class Builder {
        private static final String DEFAULT_BODY = "";
    
        private HttpStatus status;
        private String body;
        
        public Builder() {
            body = DEFAULT_BODY;
        }
        
        
        public Builder setStatus(HttpStatus status) {
            this.status = status;
            return this;
        }

        public Builder setBody(String body) {
            this.body = body;
            return this;
        }

        public ResponseEntity build() {
            return new ResponseEntity(status, body);
        }        
    }
}

Request params으로 Model 객체 생성하기 : ModelInitializer 생성

  • reflection API 사용해서 생성하기 : 요청받은 targetType에 맞게 객체 생성
    • declared와 일반 메소드 차이 : 해당 클래스에만 선언되어있는 것을 찾아오는 것과 상위 클래스에 선언되어있는 것을 모두 가져오는 차이
    • 자바빈 규약에 맞게 모델 추상화해야함 : 약속이 되어있는 것을 꼭 지켜야함
public class ModelInitializer {
    public static <T> Optional<T> init(Map<String, String> params, Class<T> targetType) {
        try {
            T instance = targetType.getDeclaredConstructor().newInstance();
            List<Method> injectTargets = Arrays.stream(targetType.getDeclaredMethods()).filter(method -> method.getName().startsWith("set")).collect(toList());
            .
            .
            .
            .
            return Optional.of(instance);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            return Optional.empty();
        }
    }
}
  • 수정할 부분이 있다면 injection 해주는 방식이 달라진다면? 자바빈 규약이 아니라 새로운 규약이 나와서 뭔가 다르게 동작해야한다면?
    • injection 해야하는 대상을 뽑는 기준을 전략 패턴처리하면 됨 : ModelInitializer의 메소드가 static이 아니라 instance 메소드로 변경하고, 대상 뽑는 기준을 injection 할 수 있도록 변경하면 더 낫지않을까싶음

객체지향적인 코드인지 아닌지 계속해서 의심하기

  • 혹시 다른 객체의 상태를 get해서 마음대로 변경하고 있는 것은 아닌지
  • 많은 것(관심, 역할)을 하나의 객체가 처리하고 있는 것은 아닌지

jpa

연관관계 맵핑

  • 연관관계 맵핑의 핵심은 객체지향적으로 관계를 맺는다는 것
    • 데이터 중심적으로 했다면 관계를 맺는 것이 아니라 그냥 fk를 가지고 있는 것
    • 객체지향적으로 했다면 참조변수를 가지고 있는 것(객체의 참조와 테이블 행의 key를 맵핑)
    • 코딩을 할 때(설계할 때) 참조변수를 가지는 것과 fk를 쌩으로 가져있는 것은 큰 차이가 있음 : 객체지향적으로 코딩을 할 수 있다는 장점이 생김(내부적으로 쿼리를 날리는 것은 같으나 OOP 개발자는 OOP를 그대로
  • 연관관계 맵핑할 때 주의할 점은 맵핑할 key가 할당되어있어야함 : jpa로 관리하는(영속), 관리했던(준영속 - id는 주어져있는) 엔티티 객체여야함