본문 바로가기
Java/Java

정적 팩토리 메서드, 인스턴스 캐싱

by oneny 2023. 4. 30.
TDD, 클린 코드 with Java - 로또 미션

 

 

GitHub - oneny/java-lotto: 로또 게임 구현을 관리하는 저장소

로또 게임 구현을 관리하는 저장소. Contribute to oneny/java-lotto development by creating an account on GitHub.

github.com

한 사람이 LottoTicket 10장을 산 경우 60개의 LottoNumber 객체가 생성된다.

여기서 문제점은 LottoNumber는 1 ~ 45의 고정된 값인데에도 불구하고 같은 번호라도 새로운 인스턴스를 생성하고, 가비지 컬렉션 등 부담이 될 수 있다. 즉, 로또를 사려는 사람이 1만명인 경우 10장씩 사면 서로 다른 LottoNumber 인스턴스 60만개가 생성되는 것은 너무 큰 낭비이다.

프리미티브 값은 내부적으로 새로운 인스턴스를 생성하지 않고 값을 재사용하지만 LottoNumber는 Wrapper Class로 만들었기 때문에 같은 번호에 대해서도 새로운 인스턴스를 생성하고 있다. 따라서 Wrapper Class로 만든 LottoNumber를 다시 프리미티브 값으로 만들어야 할까?

No! 정적 팩토리 메서드인스턴스 캐싱을 프로그래밍에 적용하여 매번 새로운 인스턴스를 생성하는 것이 아니라 하나를 미리 생성한 후 재사용할 수 있도록 만들 수 있다.

 

정적 팩토리 메서드

정적 팩토리 메서드는 쉽게 말해 객체 생성을 흔히 사용하는 생성자가 아닌 정적(static) 메서드로 하는 것을 정적 팩토리 메서드라고 한다.

실제로 정적 팩토리 메서드는 단순히 생성자의 역할을 대신 이행하는 것 뿐만 아니라 개발자가 좀 더 가독성 좋은 코드를 작성하고 객체 지향적으로 프로그래밍할 수 있게 도와주기 때문에 실무에서도 사용되고 있다.

 

 

정적 팩토리 메서드 특징

  1. 생성 목적에 대한 이름 표현이 가능하다
  2. 인스턴스에 대해 통제 및 관리가 가능하다.
  3. 하위 자료형 객체를 반환할 수 있다.
  4. 인자에 따라 다른 객체를 반환하도록 분기할 수 있다.
  5. 객체 생성을 캡슐화 할 수 있다.

2번 인스턴스에 대한 캐싱(Caching) 절차 구조를 정적 팩토리 메서드로 구현하여 같은 번호의 LottoNumber 인스턴스를 재사용하여 메모리 절약할 수 있도록 만들 예정이다.

 

 

정적 팩토리 메서드 적용

먼저 정적 팩토리 메서드를 사용하여 LottoNumber 객체를 생성하도록 만들기 위해서 다음과 같이 작성했다. 하지만 이렇게만 작성하면 아래 테스트 코드에서 실패를 하게 된다.

 

정적 팩토리 메서드 테스트

당연히 둘은 다른 인스턴스이기 때문에 해당 테스트는 fail할 수 밖에 없다. 따라서 인스턴스 캐싱을 적용하여 같은 번호인 LottoNumber 객체라면 새로운 인스턴스가 아닌 재사용할 수 있도록 만들어 보자.

 

인스턴스 캐싱 적용

이렇게 하면 자주 사용하는 인스턴스를 캐싱하여 꼭 프리미티브 값이 아니더라도 LottoNumber Wrapper Class를 같은 번호에 대한 LottoNumber는 같은 인스턴스를 반환하도록 재사용하게 만들 수 있다.

 

인스턴스 캐싱 테스트

이제 60만개의 인스턴스를 만들도록 낭비하지 않고 한 번 만든 45개의 인스턴스를 재사용하도록 만들어 성능을 개선할 수 있다.

 

출처

 

정적 팩토리 메서드 사용법 - 완벽 마스터하기