이번 미션에서 카드덱을 구성하기 위해서 모양과 숫자를 가진 카드를 만들어야했다. 만약 카드덱에 있는 카드를 모두 사용하게 된다면, 새로운 카드덱을 만들어야 하는데 이때 카드가 캐싱되어있다면 카드 인스턴스를 새로 만들 필요가 없고 같은 인스턴스를 갖도록 만들면 된다. 이를 캐싱이라 하고, 도입해봤다.
사실 캐싱이라는 개념은 그리 낯선 개념은 아니다. equals로 비교했을 때는 참조값을 비교하기 때문에 true로 나오는게 당연하지만 두번째 테스트의 경우 서로 다른 인스턴스여서 false가 나올 것 같지만, 실제 결과는 true가 나온다.
Integer num1 = 1;
Integer num2 = 1;
assertThat(num1.equals(num2)).isTrue(); // true
assertThat(num1 == num2).isTrue(); // true
이렇게 결과가 나오는 이유는 IntegerCache
에서 캐싱하기 때문에 캐싱한 인스턴스를 반환하기 때문에 같은 인스턴스를 갖고있다고 나오게 된다.
블랙잭에서는 이를 카드에 적용해볼 수 있었다.
public class Card {
private static final List<Card> CACHE = createCards();
private final CardNumber number;
private final CardSymbol symbol;
private Card(CardNumber number, CardSymbol symbol) {
this.number = number;
this.symbol = symbol;
}
private static List<Card> createCards() {
return Arrays.stream(CardSymbol.values())
.flatMap(symbol -> createSymbolCards(symbol).stream())
.collect(Collectors.toList());
}
private static List<Card> createSymbolCards(CardSymbol cardSymbol) {
return Arrays.stream(CardNumber.values())
.map(cardNumber -> new Card(cardNumber, cardSymbol))
.collect(Collectors.toList());
}
public static List<Card> createCardDeck() {
return new ArrayList<>(CACHE);
}
}
정적 팩토리 메서드를 이용해서 클래스 초기화시에 캐싱을 해놓고, cardDeck을 생성해달라고 하면 card의 뭉치를 받아올 수 있도록 구현했습니다. 이렇게 구현하면 중복해서 사용되어질 인스턴스들이 계속 생기지 않아서 메모리 낭비를 줄일 수 있습니다.
스티치 덕분에 캐싱을 직접 사용해볼 수 있었고, 사소해 보이지만 성능에 영향을 미칠 수 있는 요소들을 제어해주면서 개발하게되니 재밌었습니다.
https://tecoble.techcourse.co.kr/post/2020-06-24-caching-instance/