- 리팩터링은 습관화 되어야 하는 것임
- 템플릿에 대해 학습하기 전에 WebApiExRateProvider를 간단 리팩터링 해보자
// 기존
public class WebApiExRatePaymentService extends PaymentService {
@Override
BigDecimal getExRate(String currency) throws IOException {
URL url = new URL("<https://open.er-api.com/v6/latest/>" + currency);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = br.lines().collect(Collectors.joining());
br.close();
System.out.println(response);
ObjectMapper mapper = new ObjectMapper();
ExRateData data = mapper.readValue(response, ExRateData.class);
BigDecimal exRate = data.rates().get("KRW");
System.out.println(exRate);
return exRate;
}
}
// 리팩터링
public class WebApiExRateProvider implements ExRateProvider {
@Override
public BigDecimal getExRate(String currency) {
String url = "<https://open.er-api.com/v6/latest/>" + currency;
URI uri;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
String response;
try {
HttpURLConnection connection = (HttpURLConnection) uri.toURL().openConnection();
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
response = br.lines().collect(Collectors.joining());
}
System.out.println(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
ObjectMapper mapper = new ObjectMapper();
ExRateData data = data = mapper.readValue(response, ExRateData.class);
BigDecimal exRate = data.rates().get("KRW");
System.out.println("API ExRate: " + exRate);
return exRate;
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
- URL은 Deprecated 예정인 객체 사용 X
- URI로 전환하고 URL이 필요하면 toURL()로 변환
- Checked Exception에 대하여 throws 로 명시하지 않도록 변경
- 이를 사용하면 그 메서드에 연결되어 있는 모든 기능에 throws가 붙어야 하는 문제가 생김
- 따라서 try…catch 문으로 예외를 잡아 Unchecked 예외인 RuntimeException으로 전환
- 리소스에 대한 해제 처리를 효율적으로 하기 위한 수정 (메모리 누수 방지를 위해)
- 기존엔 BufferedReader를
br.close() 이렇게 명시적으로 리소스 해제 시킴
- 하지만 try with resource 문을 활용하면, 직접 명시적으로 호출하지 않아도 알아서 close 함
- 가능한 이유
- BufferedReader 를 타고 가면 AutoClosable 타입이란 걸 알 수 있고, AutoClosable 은 close 라는 메서드를 가지고 있음
- 즉, AutoClosable 인터페에스를 구현한 Object를
try with resource 문의 () 안에서 선언을 해두면, 이 블록이 마무리되기 전에 반드시 해당 리소스를 close 해줌