개발하면서 API 응답 값으로 Map으로 넘겨주거나 DTO 클래스나, ErrorResponse등 클래스를 넘겨주는 방식으로 사용합니다. 하지만 알기로는 응답 값이든 데이터를 주고받는 데 있어서 대부분 Map 의 사용을 지양하라고 합니다.
왜 그런지 간단하게 알아보겠습니다.
Map의 사용을 지양하는 이유가 무엇일까요?
Map을 사용할 때의 단점은 다음과 같습니다.
- 컴파일 에러를 유발할 수 없음
- key 또는 value가 null이면 Map의 해당 필드 자체를 key로 가져가지 않음.
- String 텍스트를 Key로 사용함
- 가독성이 떨어짐
- 타입캐스팅 비용이 발생함
- 불변성을 확보할 수 없음
1. 컴파일 에러를 유발할 수 없음
Map의 Value는 Object 타입이다. 그리고 Object 클래스는 최상위 클래스이기 때문에 어떠한 데이터도 받아드릴 수 있다. Object를 사용할 때의 문제는 어떠한 데이터도 받아드릴 수 있기 때문에 타입 체크를 할 수 없다는 것이다. 만약 long 타입을 넣어줘야 하는데, int 타입을 넣어줘도 해당 코드는 컴파일 에러를 유발하지 않는다.
Map<String, Object> map = new HashMap<>(); // long이 아닌 int를 넣어도 컴파일 에러가 발생하지 않음 -> Object 타입이기 때문 map.put("height", 180);
만약 이러한 문제가 실제 코드에 있다면, 우리는 이러한 문제를 런타임 시점에 알게 될 것이다. 그렇기 때문에 타입에 대해 엄격하게 가져가고, 컴파일 에러를 얻기 위해서 DTO를 사용하는 것이 좋다.
2. key 또는 value가 null이면 Map의 해당 필드 자체를 key로 가져가지 않음.
3. String 텍스트를 Key로 사용함
Key로 String을 사용한다는 것은 문제가 발생할 여지가 항상 열려있다는 것입니다. Key에 오타를 넣고 우리가 인지하지 못하면 불필요한 시간을 쏟게 될 것입니다. 굳이 문제의 가능성을 열어두고 이로 인해 시간 낭비의 여지를 줄 필요가 없습니다. DTO를 이용하면 이러한 문제를 해결할 수 있습니다.
4.가독성이 떨어짐
Map 을 쓰게 되면 해당 데이터가 어떠한 데이터를 갖고 있는지 우리는 다시 읽어보는 수고가 생깁니다. 그로 인하여 개발 생산성 또한 떨어지게 됩니다.
5.타입캐스팅 비용이 발생함
Map의 Value를 사용하기 위해서는 반드시 타입 캐스팅을 해야합니다.
String name = (String) map.get("name");
그리고 이러한 타입 캐스팅은 당연히 컴퓨팅 비용을 필요로 합니다. 만약 꺼내야 하는 데이터가 많다면 이러한 비용은 더욱 증가하게 됩니다.
6. 불변성을 확보할 수 없음
Map을 사용하면 해당 데이터의 불변성을 확보할 수 없습니다. 만약 누군가가 실수로 put 코드를 추가하였다면 기존의 데이터는 없어지고 잘못된 데이터로 덮어 씌워집니다.
Map<String, Object> map = new HashMap<>(); map.put("name", "Jiwoo"); // 불변성을 확보할 수 없고 값이 변경될 수 있음 map.put("name", "JilDong");
불변성을 확보하는 것은 불필요한 시간을 절감할 수 있어 상당히 중요합니다. 하지만 Map을 사용하면 불변성을 확보할 수 없으니 DTO를 사용하는 것이 좋습니다.
관련링크