본문 바로가기

Proj/aDreamLeaf

가게 정보 관련 RequestDto

가게 정보에 필요했던 Request 클래스는 다음과 같다.

 - StoreReq

 - StoreHygradeReq

 - UserCurReq

 

이 중 하나인 StoreReq를 살펴보면 다음과 같다.

@Data
@AllArgsConstructor
@ToString
@Builder
public class StoreReq {
    private String storeName;       //store 이름
    private int zipCode;            //우편번호
    private String roadAddr;        //도로명주소
    private String lotAddr;         //지번주소
    private double wgs84Lat;        //위도
    private double wgs84Logt;       //경도
    private int payment;        //아동급식카드 지원여부
    private String prodName;        //제공품목
    private String prodTarget;      //제공대상
}

 

1. 애노테이션의 오용 

 

이 클래스는 경기도 가게정보 api에서 정보를 가져와 Req를 생성자로 생성한 후, 이를 db에 저장할 때 사용된다. 즉, 생성자 외에는 사용되지 않는다. 만약 사용한다면 jpa 도입 시 Req->Entity를 위한 getter 정도 사용될 것이라 생각한다. 

 이 경우 @Data 애노테이션을 사용하게 되면 개발 중 setter를 무분별하게 사용하게 되거나, 인스턴스가 잘못 생성되는 등 안전성을 보장받을 수 없다. 즉, 필요한 함수만 애노테이션으로 구현해야 한다. 따라서 Data를 지우고, Getter를 추가한다.

 

 2. 사용처에서의 문제

 api에서 데이터를 가져와 인스턴스를 만드는 코드는 다음과 같다.(ApiManager.java line 108)

StoreReq checkFor1=new StoreReq((String) temp.get("FACLT_NM"),
                        zipcd,
                        (String) temp.get("REFINE_ROADNM_ADDR"),
                        lotno,
                        lat, logt, 0, "", "");
StoreReq checkFor2=new StoreReq((String) temp.get("FACLT_NM"),
                        zipcd,
                        (String) temp.get("REFINE_ROADNM_ADDR"),
                        lotno,
                        lat, logt, 2, "", "");

 

 생성자를 이렇게 사용하게 되면 나중에 코드에서 생성자의 순서가 바뀔 경우 데이터의 필드 값이 잘 못 저장되는 문제가 발생할 수 있다. 이를 해결하기 위해 빌더 패턴을 사용하여 구현하도록 한다.

 

                StoreReq checkFor1 = StoreReq.builder()
                        .storeName((String) temp.get("FACLT_NM"))
                        .zipCode(zipcd)
                        .roadAddr((String) temp.get("REFINE_ROADNM_ADDR"))
                        .lotAddr(lotno)
                        .wgs84Lat(lat)
                        .wgs84Logt(logt)
                        .payment(0)
                        .prodName("")
                        .prodTarget("")
                        .build();
                

                StoreReq checkFor2 = StoreReq.builder()
                        .storeName((String) temp.get("FACLT_NM"))
                        .zipCode(zipcd)
                        .roadAddr((String) temp.get("REFINE_ROADNM_ADDR"))
                        .lotAddr(lotno)
                        .wgs84Lat(lat)
                        .wgs84Logt(logt)
                        .payment(2)
                        .prodName("")
                        .prodTarget("")
                        .build();

 

 빌더 패턴을 사용하면 나중에 어떤 필드에 어떤 값이 들어가는지 읽기도 쉽고, 필드가 잘 못 입력되는 위험성도 줄어든다.

마찬가지로 ApiManager의 모든 생성자를 빌더 패턴으로 바꾸어 주었다. (ApiManager.java line 108, 122, 141, 260, 272, 379)

 

후기

첫 리팩토링이었다. 클래스 하나씩 수정할까 했는데 타고타고 갈아엎을 코드가 계속 생겨나는 것 같다. 실제로 이 서버를 운영한다는 생각으로 해봐야겠다.

 

'Proj > aDreamLeaf' 카테고리의 다른 글

Git Action을 활용한 CI/CD  (2) 2024.08.07
서브모듈 적용  (0) 2024.08.06
Hello, Refactoring!  (0) 2024.05.18